Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

hash refferences

by leonidlm (Pilgrim)
on Aug 21, 2008 at 12:17 UTC ( [id://705772]=perlquestion: print w/replies, xml ) Need Help??

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

Hi all
Just wonder, take a look at the following sample code:
my @arrayOfHashes; my %temporary; foreach $val (@variables) { # Here I populate a temporary hash # # .... # push @arrayOfHashes, \%temporary; %temporary = undef; }
My question is why after I assign a reference to an object and then I loose the original reference to it (by assigning another value -> undef) The original hash in the array is changed too!
Thanks.

Replies are listed 'Best First'.
Re: hash references
by moritz (Cardinal) on Aug 21, 2008 at 12:21 UTC
    Assigning undef to a hash doesn't "destroy" the hash. I t just empties it.
    my %h = (1, 2); print bless(\%h), $/; %h = undef; print bless(\%h), $/; __END__ main=HASH(0x99ae63c) main=HASH(0x99ae63c)

    It's the same memory address after assigning undef.

    The usual way to do it is to declare the hash inside the loop:

    for $val (@variables) { my %temp; # work with %temp here; push @array, \%temp; }

    That way a new variable is generated for each iteration.

      But whats the difference between the following:
      1. Declaration of the %temp inside the loop
      2. Performing: undef %temp at the end of each iteration
      Someone ?

        They are completely different. undef %temp empties the variable but still keeps the variable there, while a lexical variable goes out of scope. The undef %temp acts on the values, while leaving the scope acts on the binding of the name to the value.

        What Corion said is right.

        %temp is actually a container - think of a bucket. You can fill this container (putting water into the bucket), and empty it, which is what %temp = undef does.

        Or you can but your bucket into the cupboard, (pushing it to an array), and take a new bucket (declaring %temp inside the loop).

        In this real-world analogy you can see that there's a huge difference between these two things.

      Another thing: Unfortunately I can't release the %temp variable every loop iteration, I need to perform it on demand. How I can do it ?
        push @array, { %temp };

        That actually copies the items from %temp into an anonymous hash, and returns its reference.

        See perlreftut and perlref for more details.

        You can't. You can store copies of the values in another variable maybe.

Re: hash refferences
by Corion (Patriarch) on Aug 21, 2008 at 12:20 UTC

    The reference still points to the same place as %temporary, so changing one will also change the other. I suggest the following code:

    foreach my $val (@variables) { my %temporary = ...; push @arrayOfHashes, \%temporary; };

    %temporary is not a reference and hence you can't "lose" the reference to its data.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://705772]
Approved by Corion
Front-paged by injunjoel
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (4)
As of 2024-04-25 13:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found