blueapache has asked for the wisdom of the Perl Monks concerning the following question:

Having trouble printing this structure, thought the code at the bottom should work. What should I be doing
#!/usr/bin/perl my %Recipes = ( "YumYumStuff" => { ingredients => [ { 1 => "1 Pate a Bombe", 2 => "1/2 French Meringue", 3 => "300ml double cream", 4 => "3 very ripe bananas", 5 => "2 tablespoons Creme de Banane", 6 => "1 Bitter Chocolate Sorbet", }, ], instructions => [ { 1 => "Whisk together the pate a bombe and the Fr +ench Meringue mixtures. They should be roughly equal in amounts by v +olume.", 2 => "Lightly whip the cream to the same consi +stency as the pate de bombe and French Meringue mixture then mix both + mixtures together", 3 => "Finally, whisk in the banana puree and l +iquer. Pour or pipe into ramekins, a long loaf tin or a large freeze +r container. ", 4 => "About 30 mins before serving, transfer t +he parfait from the freezer to the refrigerator", }, ], }, ); for $recipe (keys %Recipes) { print "For $recipe the ingredients are :\n"; $ref = $Recipes{$recipe}{ingredients}; print map "$_ = $ref{$_}\n", sort keys %{$ref}; }

Replies are listed 'Best First'.
Re: How do I print nested hashes
by davido (Cardinal) on Aug 30, 2004 at 08:30 UTC

    You've got a few problems, not the least of which is that your datastructure isn't a nested hash of hashes. It's a hash of lists of hashes, or something wierd like that. Use Data::Dumper to view the datastructure first to see how it doesn't match what you're trying to print.

    You should also construct your map statement like this:

    print map "$_ = $ref->{$_}\n", sort keys %{$ref};

    Note the $ref->{$_} construct. You have to dereference the hashref $ref.

    Here's code that works. It's sloppy because you're still not using strict, not using warnings, formatting is all over the place, etc. But it does what you're after:

    my %Recipes = ( "YumYumStuff" => { ingredients => { 1 => "1 Pate a Bombe", 2 => "1/2 French Meringue", 3 => "300ml double cream", 4 => "3 very ripe bananas", 5 => "2 tablespoons Creme de Banane", 6 => "1 Bitter Chocolate Sorbet", }, instructions => { 1 => "Whisk together the pate a bombe and the French Meringue +mixtures. They should be roughly equal in amounts by volume.", 2 => "Lightly whip the cream to the same consistency as the pa +te de bombe and French Meringue mixture then mix both mixtures togeth +er", 3 => "Finally, whisk in the banana puree and liquer. Pour or +pipe into ramekins, a long loaf tin or a large freezer container. ", 4 => "About 30 mins before serving, transfer the parfait from +the freezer to the refrigerator", } } ); for $recipe (keys %Recipes) { print "For $recipe the ingredients are :\n"; $ref = $Recipes{$recipe}{ingredients}; print map "$_ = $ref->{$_}\n", sort keys %{$ref}; }

    Dave

      thanks, see that you've removed the array brackets and it works. Did try to dereference, amongst a number of things :) and nothing would work.
Re: How do I print nested hashes
by Anonymous Monk on Aug 30, 2004 at 09:14 UTC
    use YAML; my %Recipes = ( YumYumStuff => { ingredients => [ { 1 => "1 Pate a Bombe", 2 => "1/2 French Meringue", 3 => "300ml double cream", 4 => "3 very ripe bananas", 5 => "2 tablespoons Creme de Banane", 6 => "1 Bitter Chocolate Sorbet", }, ], instructions => [ { 1 => "Whisk together the pate a bombe and the French " + . "Meringue mixtures. They should be roughly equal + in " . "amounts by volume.", 2 => "Lightly whip the cream to the same consistency a +s the " . "pate de bombe and French Meringue mixture then m +ix " . "bothmixtures together", 3 => "Finally, whisk in the banana puree and liquer. +Pour " . "or pipe into ramekins, a long loaf tin or a larg +e " . "freezer container. ", 4 => "About 30 mins before serving, transfer the parfa +it " . "from the freezer to the refrigerator", }, ], }, ); print Dump \%Recipes; __END__ --- #YAML:1.0 YumYumStuff: ingredients: - 1: 1 Pate a Bombe 2: 1/2 French Meringue 3: 300ml double cream 4: 3 very ripe bananas 5: 2 tablespoons Creme de Banane 6: 1 Bitter Chocolate Sorbet instructions: - 1: ! >- Whisk together the pate a bombe and the French Meringue mixtur +es. They should be roughly equal in amounts by volume. 2: ! >- Lightly whip the cream to the same consistency as the pate de +bombe and French Meringue mixture then mix bothmixtures together 3: >- Finally, whisk in the banana puree and liquer. Pour or pipe i +nto ramekins, a long loaf tin or a large freezer container. 4: ! >- About 30 mins before serving, transfer the parfait from the fr +eezer to the refrigerator
      thanks, will give that a go
Re: How do I print nested hashes
by Eimi Metamorphoumai (Deacon) on Aug 30, 2004 at 15:25 UTC
    Since no one else has mentioned it, are you sure that nested hashes are appropriate here? In particular, you seem to have a hash mapping consecutive small integers to values. You might consider using an array for that instead. Something like
    my %Recipes = ( "YumYumStuff" => { ingredients => [ "1 Pate a Bombe", "1/2 French Meringue", "300ml double cream", "3 very ripe bananas", "2 tablespoons Creme de Banane", "1 Bitter Chocolate Sorbet", ], instructions => [ "Whisk together the pate a bombe and the French Meringue mixt +ures. They should be roughly equal in amounts by volume.", "Lightly whip the cream to the same consistency as the pate d +e bombe and French Meringue mixture then mix both mixtures together", "Finally, whisk in the banana puree and liquer. Pour or pipe + into ramekins, a long loaf tin or a large freezer container. ", "About 30 mins before serving, transfer the parfait from the +freezer to the refrigerator", ], } ); for $recipe (keys %Recipes) { print "For $recipe the ingredients are :\n"; $ref = $Recipes{$recipe}{ingredients}; my $i; print map ++$i." = $_\n", @$ref; }
      I agree - arrays seem to be a good choice here. Using arrays would also make inserting or deleting an ingredient or instruction step very easy (simply push/splice/slice as necessary). Hashes would make those modifications more difficult, since you'd have to renumber the keys after every change.
Re: How do I print nested hashes
by chanio (Priest) on Aug 31, 2004 at 17:48 UTC
    Shouldn't it read better this way?

    Without the numbers, just showing the quantities incolumned.

    1 Pate a Bombe 1/2 French Meringue 300ml double cream 3 very ripe bananas 2 tablespoons Creme de Banane 1 Bitter Chocolate Sorbet

    print "$1 \t $2" if (/^([^ ]+)\s*(.*)/); ##separates by 1st. blank
    .{\('v')/}
    _`(___)' __________________________