Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

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 (Chancellor) 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 one hand claps...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (3)
As of 2018-05-24 20:30 GMT
Find Nodes?
    Voting Booth?