in reply to Re: print array of hashes
in thread print array of hashes

$num_kids = (scalar @{$rec[0]{kids}}); $num_kids = scalar (@{$rec[0]->{kids}});
both these work...would someone be so kind as to explain each of them?

Replies are listed 'Best First'.
Re^3: print array of hashes
by choroba (Cardinal) on Apr 22, 2010 at 14:46 UTC
    @rec is an array of hashrefs, therefore $ref[0] is a hashref. The arrow is optional here, we have two possible ways to get the value of the kids key. The value is an arrayref, so we dereference it with @{} to get the array. And scalar applied to a list an array returns the number of elements in it.

    Update: rephrased because of almut's reply.

      And scalar applied to a list returns the number of elements in the list.

      That statement could be misleading...:

      $num = scalar ( qw(foo bar) ); print $num; # "bar", not 2!

      A list (as opposed to an array) in scalar context evaluates to its last element.

      this site amazes me...the helpfulness of the participants is something else...thanks, all.
Re^3: print array of hashes
by Marshall (Canon) on Apr 22, 2010 at 17:38 UTC
    When you see an index like [0] in Perl code, this is a RED alert that probably something is wrong, not always but, more likely than not!!

    You have an array of "pointers" to anon hashes. Data::Dumper is a SUPER cool thing to help visualize what is going on.

    Below, I have a foreach loop that processes every hash_ref in @rec.
    $hash_ref->{'name'} yields the name in that record
    @{$hash_ref->{'kids'}} is a bit trickier. If this was just one kid, then it would work like a name. But there are multiple kids and this is an array of kids.
    Below I show how to print @demo. $hash_ref->{'kids'} fetches one thing just like accessing $hash_ref->{'name'} did. But now we have to de-reference that single thing which is a "pointer" to array. In Perl when you have a "subscripted thing" and you want to de-reference it, you need to enclose it in brackets,{}. I did that, then I said that this is an array de-reference '@' and bingo, this is now just like printing @demo. In other words, you need to tell "@" what to operate upon. @$hash_ref->{'kids'} would mean something completely different. I want "@" to operate not just upon the value $hash_ref, but upon the whole thing that {$hash_ref->{'kids'}} "points to".

    An array in a scalar context is the number of things in that array. I think others have covered that point.

    #!/usr/bin/perl -w use strict; use Data::Dumper; my @demo =('xyz', 'qrs'); my @rec = ( { name => 'Nancy', address => 613, kids => ['abc', 'def'], }, { name => "Betty", address => 845, kids => ['xyz', 'qrs'], }, ); print Dumper \@rec; print "DEMO: @demo\n"; foreach my $hash_ref (@rec) { print "$hash_ref->{'name'} struggles with: ", "@{$hash_ref->{'kids'}}\n"; } __END__ $VAR1 = [ { 'name' => 'Nancy', 'kids' => [ 'abc', 'def' ], 'address' => 613 }, { 'name' => 'Betty', 'kids' => [ 'xyz', 'qrs' ], 'address' => 845 } ]; DEMO: xyz qrs Nancy struggles with: abc def Betty struggles with: xyz qrs
Re^3: print array of hashes
by dmlond (Acolyte) on Apr 22, 2010 at 20:18 UTC

    There are a couple of things going on here.

    First, you have the difference between:

    $val = (EXPRESSION);
    and
    $val = EXPRESSION;
    Here the parentheses act like they do in basic math, so, in this case, the two operations are identical.

    Next you have the difference between:

    scalar ARGS;
    and
    scalar(ARGS);
    For many perl functions (such as scalar), the parentheses surrounding the arguments are optional. It often reads more like a natural human sentence if you omit them, but often it is better to explicitly include them if the resulting statement does not read well as a natural human sentence.

    You might also want to know what @{EXPRESSION} means. This is how to dereference an array reference in perl. If $val holds a reference to an array (e.g. it does not hold the array itself), then @{$val} returns the actual array. Similarly you can use %{$val} to dereference the hash referenced by $val, ${$val} to dereference the scalar referenced by $val, and &{$val} to dereference the subroutine referenced by $val, with @{$val}(ARGS) if you need to pass arguments.

    Finally, there is the difference between:

    $rec[0]{kids}
    and
    $rec[0]->{kids}
    Each element in the @rec array is itself a reference to a hash. Perl provides these two ways to access the scalar held as a value in a hashref, which only differ in the use of the '->' operator. I recommend always using the '->' operator, which explicitly means 'the thing referenced by'. It is much more self documenting. $rec[0]->{kids} is the value keyed to 'kids' in the hash referenced by $rec[0]. Similarly, $array_ref->[0] is the first element in the array referenced by $array_ref, and $code_ref->() is the subroutine referenced by $code_ref. Also, $code_ref->(ARGS) is much more pretty than @{$code_ref}(ARGS). When you get into multidimensional data structures, the '->' can be very helpful. Compare the identically functioning:
    ${$aref}[0]{kids}[0]{first_name}
    and
    $aref->[0]->{kids}->[0]->{first_name}
    The last one is much more self-documenting, and really starts to look more like an object (which also uses '->' for attributes and methods, which should give you the impression that it is pretty powerful magic).