Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

The Drivel is in the Details

by dalgetty (Novice)
on May 29, 2007 at 22:16 UTC ( #618063=perlquestion: print w/replies, xml ) Need Help??
dalgetty has asked for the wisdom of the Perl Monks concerning the following question:

O Holy Brethren,

My code works fine. It's just that I am using it in a manual, and I have to justify and explain each detail. This section of my package takes a hash-array-hash from XML::Simple and prints out the contents successfully
foreach my $node(keys (%$source)) { my $elem=$source->{$node}; my $count=0; foreach my $attr (@$elem) { $self->print.="\n\n$node $count\n\n"; if ($count<1) {$self->nodename=$node;} foreach my $subnode(keys(%$attr)) { $self->print.=$subnode."\t".$attr->{$subnode}."\n"; } $count++; } }
Why is the -> necessary in $source->{$node}, and why the %$ and @$ symbols instead of just % and @?

In smaller, non-module scripts I use this kind of format:
foreach $label (keys %contact) { print"$label:$contact{$label}\n";
Forgive my ignorance, and peace be with you


Replies are listed 'Best First'.
Re: The Drivel is in the Details
by jZed (Prior) on May 29, 2007 at 22:24 UTC
    $source is a reference to a hash. You find the keys by de-referencing it (%$source) then you dereference it with the arrow in $source->{node}. You could use the format you are used to if you do something like:
    my %newSource = %$source; # dereference it all at once foreach my $node(keys (%newSource)) { # note no %$ #... $newSource{$node}; # already dereferenced.

    update I'm not recommending that you change the code, but showing a similar situation to explain the code. If you are thinking of changing the code, see the important caveat mentioned by Random_Walk.

      Thank you - I think I can explain it from there.


      I think you should point out that when you do

      my %newSource = %$source; # dereference it all at once
      you are not just dereferencing $source but making a new and independent copy in %newSource. This may have implications if the code evolves. Any change made to one array will not be reflected in the other, for instance an element removed from %$source is not removed from %newSource and the removal of $source will not imply removal of %newSource


      Pereant, qui ante nos nostra dixerunt!
Re: The Drivel is in the Details
by FunkyMonk (Canon) on May 29, 2007 at 22:40 UTC
    • XML::Simple returns a reference to a hash.
    • %$ and @$ are used to get a hash and array respectively from a reference (dereferencing)
    • -> is shorthand for dereference-and-access of an array or hash
    • -> allows you to use $source->{$node} instead of %{$source}{$node}
    • -> is also used to call an object's method as you did in $self->print. $self is the object and print is the method
Re: The Drivel is in the Details
by blazar (Canon) on May 29, 2007 at 23:01 UTC
    Why is the -> necessary in $source->{$node}

    Because $source is a (hash) reference and it needs to be dereferenced.

    and why the %$ and @$ symbols instead of just % and @?

    Because the symbols are still simply % and @, but now you're using them to dereference something that is held in a scalar, which is prefixed by the $ sigil: this is another method for dereferencing, and in its full blown form it should be:

    %{ $hashref }

    But in this simple case the curlies can be omitted. In more complex contructs, they cannot.

Re: The Drivel is in the Details
by BenHopkins (Sexton) on May 31, 2007 at 04:10 UTC
    %$ and @$ indicate that the variable is a hash-REF and an array-REF. Kinda like a C cast.

    Don't know about the -> in $source->{$node}, though.

Re: The Drivel is in the Details
by chexmix (Hermit) on May 31, 2007 at 18:45 UTC

    "Why is the -> necessary in $source->{$node}"

    IIRC, in the "Alpaca book" the authors make the point that this arrow is optional "between subscripty kinds of things" but NOT in a case like this.

    perlreftut also states: "In between two subscripts, the arrow is optional." If you are working with an array reference, the perlreftut continues, "instead of $a[1]->[2], (you) can write $a[1][2]."

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://618063]
Approved by Corion
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (6)
As of 2017-06-25 17:41 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (568 votes). Check out past polls.