This sounds suspiciously homework-ish, so I'll point you towards some references which will help you work this out yourself:
- perldsc
- perlref
- References quick reference
- And for printing out the data structure try: Data::Dumper
Hope this helps, if you get stuck with code - post a reply with any erros / output that is appropriate and see what the Monastery comes up with.
Just a something something...
| [reply] |
my $kids= scalar @{$rec[0]{kids}};
If you want the sum of kids in all records you just have to add a loop around that line:
my $kids;
foreach my $record (@rec) {
$kids+= scalar @{$record->{kids}};
}
| [reply] [d/l] [select] |
| [reply] [d/l] [select] |
True as that may be, sometimes it feels more comfortable to be explicit about what you mean. For example (and let's keep it simple):
my $total_price = ($item_price * $item_quantity) + $shipping_cost
In that example the parentheses aren't necessary because multiplication already has higher precedence than addition anyway, but I feel it improves readability.
| [reply] [d/l] |
thanks
Not homework (school-type that is)...but a self-learning session.
| [reply] |
$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? | [reply] [d/l] |
| [reply] [d/l] [select] |
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
| [reply] [d/l] [select] |
$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).
| [reply] [d/l] [select] |
See the following Example:
my @rec = (
{
name => 'Nancy',
address => 613,
kids => [abc, def]
},
.
.
);
.
.
print scalar(@{$rec[0]->{kids}});
| [reply] [d/l] |