Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

autovivication and referencing

by Amblikai (Scribe)
on Nov 20, 2013 at 13:25 UTC ( #1063518=perlquestion: print w/replies, xml ) Need Help??
Amblikai has asked for the wisdom of the Perl Monks concerning the following question:

Hi Folks, probably a rubbish title but i was wondering if these 2 scenarios are equivalent: Scenario 1:
my %other_hash=( param1 => val1, param2 => val2 ); my %hash=( key1 => value, key2 => \%other_hash );
Scenario 2:
my %hash=( key1 => value, key2 => ( param1 => val1, param2 => val2 ) );
Will the value for key2 be the same in both cases? (A hash reference?) Thanks.

Replies are listed 'Best First'.
Re: autovivication and referencing
by hdb (Prior) on Nov 20, 2013 at 13:28 UTC

    A very valuable tool is Data::Dumper that let's you inspect the contents of variables. In your case:

    use Data::Dumper; print Dumper \%hash;

    will show you that the two scenarios are not the same.

    With Data::Dumper you can figure out most of these kind of questions.

      Ah i use Dumper all the time, i just didn't think of it in this case! Thanks! So if i was to "hard code" this complex data structure. Would i have to write it the first way with a separate "other_hash" declaration? Or can i write it somehow similarly to the second way? (The first one is what i want).

        No, just say key2 => { ... }, ie use braces instead of parentheses.

        perldsc is your friend, look at HASHES OF HASHES.

Re: autovivication and referencing
by sundialsvc4 (Abbot) on Nov 20, 2013 at 14:11 UTC

    Also keep in mind that the first scenario specifies a reference to a variable, other_hash.   So, you now have two or more references to the same chunk of storage.   (Fortran calls that EQUIVALENCE.)

    Data::Dumper makes this clear.   Consider this:

    use strict; use warnings; use Data::Dumper; my @a = (1, 2); my $b = { "c"=>\@a }; print Dumper(\@a, $b); $b->{"c"}[0]=4; print Dumper(\@a, $b);'
    $VAR1 = [ 1, 2 ]; $VAR2 = { 'c' => $VAR1 }; $VAR1 = [ 4, 2 ]; $VAR2 = { 'c' => $VAR1 };

    The dumper knows that the hash-key points to the same block of storage that the array-variable does, so it refers to it in the second case by its name.   And you can see how a change, made by means of the hash-key, changed the value in the array variable, because the two are the same.   This is a very easy mistake to make in a production setting.

    Also note that “references” will work in this way, whether-or-not a particular reference comes into existence by means of the “autovivification” feature.

Re: autovivication and referencing
by eye (Chaplain) on Nov 20, 2013 at 15:32 UTC
    While I don't disagree with what the details of the replies from hdb & sundialsvc4, I think we need to step back and be less literal.

    The value associated with a hash key can only be a scalar. Setting the value to a list or a hash is an obfuscation at best. In this case, I would call it a coding error. Perl does what was requested, but not what was wanted. hdb's second reply shows how to correct the error by using braces to create a hash ref. Once the error is corrected, these scenarios are equivalent.

    You can build a data structure piecemeal.

Re: autovivication and referencing
by thakares (Acolyte) on Nov 20, 2013 at 16:45 UTC

    While defining a hash, the key and value pair must be in scalar context.

    In your "Scenario 2:", the value of key2 must be scalar and NOT hash. You can use a reference to a hash by replacing paranthesis by a set of curly brackets to define a reference to a hash.

    my %hash=( key1 => value, key2 => { param1 => val1, param2 => val2 } );

    Scenario 1 seems OK.

    Now Autovivification:


    $hash{key2}->{param1} now will be val1

    It just like JSON of Javascript!

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (7)
As of 2017-04-28 13:23 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (521 votes). Check out past polls.