This is cross posted on The Perl Guru forum (http://perlguru.com/gforum.cgi?post=80149;sb=post_latest_reply;so=ASC;forum_view=forum_view_collapsed;;page=unread#unread) and apparently also on SO. It is considered polite to inform the reader about cross-posts to avoid duplicate work at various places of the Internet.

I have provided two answers on the Perl Guru. Just to repeat here: the autovivification module or the hard manual way, quickly demonstrated here under the Perl debugger:

DB<1> $h{a}{b}{c} = 2; DB<2> print "foo" if defined $h{d}{e}{f} ; DB<3> print "foo" if $h{g} && $h{g}{h} && $h{g}{h}{i}; DB<4> x \%h; 0 HASH(0x600500b60) 'a' => HASH(0x600509d30) 'b' => HASH(0x600500a88) 'c' => 2 'd' => HASH(0x600500c38) 'e' => HASH(0x600500980) empty hash DB<5>
Line 1 (DB<1>) is just creating the hash, to make sure it exists.

Line 2 is checking for the definedness of a deeply nested element of the hash.

Line 3 is doing the same thing, but level by level. If the first conditional expression is false, the others will not be evaluated because they are short-circuited (the whole expression cannot be right if the first one is wrong (undefined).

Line 4 prints out the structure of the hash. You can see that line 2 created all the level below the last one (autovivification of levels 1 and 2), where as line 3 did not produce any autovivification (did not create subentries for the lower levels).

Update: corrected the case of the initial letter of the autovification module, which is lc, no uc as I originally wrote. Thanks to AnomalousMonk for the correction and for providing a link.

In addition, please note that the tests described in the debugger session above are really a quick example and that they might fail if the value in the most deeply nested value may be an end value rather than a reference to another sub-hash, in which case the test might return false despite the value being defined, if that value is itself false (for example 0 or the empty string). So that, depending on what the exact purpose of the test really is, it might sometimes be better or more reliable to rewrite line DB<3> above as:

print "foo" if $h{g} && $h{g}{h} && exists $h{g}{h}{i};
or possibly:
print "foo" if $h{g} && $h{g}{h} && defined $h{g}{h}{i};
The best solution between the three solutions really depends on what exactly you are trying to know and what the data structure really is (if you are guaranteed that the third nesting level cannot be an end value, but can only be a reference or not exist, then you don't need to worry about that, as a defined reference is always going to evaluate to true). All this to say that this was just an example, you'll need to adapt the syntax to the real scenario.

Also corrected a silly mistake in the initial DB<3> line.


In reply to Re: perl: restrict perl from automaticaly creating a hash branches on check by Laurent_R
in thread perl: restrict perl from automaticaly creating a hash branches on check by alex5161

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.