in reply to perl: restrict perl from automaticaly creating a hash branches on check
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:
Line 1 (DB<1>) is just creating the hash, to make sure it exists.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 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:
or possibly:print "foo" if $h{g} && $h{g}{h} && exists $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.print "foo" if $h{g} && $h{g}{h} && defined $h{g}{h}{i};
Also corrected a silly mistake in the initial DB<3> line.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: perl: restrict perl from automaticaly creating a hash branches on check
by AnomalousMonk (Archbishop) on Nov 06, 2014 at 19:39 UTC | |
|
Re^2: perl: restrict perl from automaticaly creating a hash branches on check
by alex5161 (Novice) on Nov 06, 2014 at 19:32 UTC | |
by Laurent_R (Canon) on Nov 07, 2014 at 07:53 UTC | |
|
Re^2: perl: restrict perl from automaticaly creating a hash branches on check
by Anonymous Monk on Nov 07, 2014 at 14:08 UTC |