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

Hi there, if someone can help me here with printing out the age in a shorter methode. here is what i am doing.
print "Alex children are $alex{children}->[1]->{age} and $alex{children}->[0]->{age} years old\n"; print "Alex is $alex{age} himself\n";
is there any shorter method/ to do so? thank you in advance.

Replies are listed 'Best First'.
Re: short method to print age.
by wfsp (Abbot) on Mar 05, 2009 at 14:45 UTC
    One way could be to extract the childrens ages into an array using map before printing them. Perhaps also consider printf to format the output.
    #!/usr/bin/perl use warnings; use strict; my %alex = ( age => 30, children => [ {age => 2}, {age => 5}, ], ); my @kids = map{$_->{age}} @{$alex{children}}; print "Alex children are $kids[0] and $kids[1] years old\n"; print "Alex is $alex{age} himself\n\n"; # or printf( qq{Alex's children are %d and %d years old\nAlex is %d himself\n}, @kids, $alex{age} );
Re: short method to print age.
by ikegami (Patriarch) on Mar 05, 2009 at 16:50 UTC

    What if Alex has three children? Who cares about shorter if it doesn't produce the right output.

    use strict; use warnings; sub plural($@) { my ($n, $s, $p) = @_; if ($n == 0) { return "no $p"; } elsif ($n == 1) { return "one $s"; } else { return "$n $p"; } } sub count_phrase { my $last = pop @_; return $last if !@_; return join(', ', @_), ' and ', $last; } sub print_person { my ($person) = @_; my $name = $person->{name}; my $age = $person->{age}; my $children = $person->{children}; if ( @$children ) { my @chd_ages = map { $_->{age} } @$children; print("$name has ", count_phrase(@$children, 'child', 'children' +), "\n"); print("The are ", phrase_list(@chd_ages), " years old\n"); } else { print("$name has no children\n"); } print("$name is $age years old\n"); } { my %person = ( name => 'Alex', age => 30, children => [ { age => 2 }, { age => 5 }, ], ); print_person(\%alex); }
Re: short method to print age.
by Roy Johnson (Monsignor) on Mar 05, 2009 at 19:20 UTC
    This mimics what you do.
    print "Alex children are \n\n " , join("\nand ", map $_->{age}, reverse @{$alex{children}}) , "years old\n";
    Obviously the reverse isn't necessary unless you really want it.

    Caution: Contents may have been coded under pressure.
      Thank you all for the answers you guys offered. i think i will end up using this code.
      #!/usr/bin/perl use warnings; %alex = ( 'name' => 'Alex', 'age' => '45'); %john = ( 'name' => 'John', 'age' => '20'); %chaddy = ( 'name' => 'Chady', 'age' => '16'); @children = (\%john, \%chaddy); $alex{'children'} = \@children; print "Alex children are \n " , join("\nand ", map $_->{age}, reverse @{$alex{children}}) , "\tyears old\n"; print "Alex is $alex{age} himself\n";
      instead of the one i mentioned above. much easier to understand i guess,thx Roy and thank you all once again.
Re: short method to print age.
by locked_user sundialsvc4 (Abbot) on Mar 05, 2009 at 15:56 UTC

    You can certainly omit some of those -> symbols if you want to.

    For example, I'm sure you could write: “$alex->{children}[1]{age}”.

    You can also write “$$alex” as a shorthand for “$alex->”.

    Just remember to be clear and consistent. Use the directives “use strict; use warnings;” as a matter of inflexible routine.

      Saving one character there isn't going to affect the length of the expression. Furthermore, -> is usually much easier to read so your suggestion actually makes things worse.

      Wasn't $$alex the original way to dereference? It was considered too confusing (or something) leading to the addition of the arrow operator.

      And you didn't even know bears could type.