Beefy Boxes and Bandwidth Generously Provided by pair Networks DiBona
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

autovivication and referencing

by Amblikai (Sexton)
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.

Comment on autovivication and referencing
Select or Download Code
Re: autovivication and referencing
by hdb (Parson) 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 (Monsignor) 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);'
    (gives...)
    $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 (Hermit) 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:

    Values:

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

    It just like JSON of Javascript!

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (14)
As of 2014-04-16 14:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (431 votes), past polls