in reply to Re: Keys() required to autovivify?
in thread Keys() required to autovivify?

I can't explain why some built-ins don't autovivify the hash, even though it needs to be flattened.

It's not about hash flattening, but the fact that arguments are passed into subroutines as references. So saying f( %{ $h } ); for an undefined $h looks up keys and values, which causes the container to spring into existence as a hash reference and be assigned to $h. That is necessary since the arguments to subs are potential candidates for assignment (lvalues)

perl -MO=Concise -le 'my $h;sub f {} f( %{ $h } );' a <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 3 <0> padsv[$h:1,4] vM/LVINTRO ->4 4 <;> nextstate(main 4 -e:1) v ->5 9 <1> entersub[t4] vKS/TARG,1 ->a - <1> ex-list K ->9 5 <0> pushmark s ->6 7 <1> rv2hv[t3] lKM/1 ->8 - <@> scope sK ->7 - <0> ex-nextstate v ->6 6 <0> padsv[$h:1,4] sM/DREFHV ->7 - <1> ex-rv2cv sK/1 ->- 8 <#> gv[*f] s ->9

(note the line padsv[$h:1,4] sM/DREFHV with the M flag), which is not the case with print.

perl -MO=Concise -le 'my $h;print( %{ $h } )' 9 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 3 <0> padsv[$h:1,3] vM/LVINTRO ->4 4 <;> nextstate(main 3 -e:1) v ->5 8 <@> print vK ->9 5 <0> pushmark s ->6 7 <1> rv2hv[t2] lK/1 ->8 - <@> scope sK ->7 - <0> ex-nextstate v ->6 6 <0> padsv[$h:1,3] s ->7

Since print doesn't comprise modifcation of it's arguments, the hashref isn't created.

That's the most concise explanation of this oddity I can conceive up to now...

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^3: Keys() required to autovivify?
by ikegami (Patriarch) on Jan 03, 2008 at 14:02 UTC

    Function arguments are always passed by reference, so they need to be real. But print's not a function. Keep in mind that the builtin functions are often called "named operators" and that Deparse shows a "print" op, not a "entersub" op. I suspect it's more along the lines of print and other builtins have their arguments built specially.

    Just guessing.

    By the way, I was getting similar results to print when using assignments.

      Yeah, but I guess it is the entersub op which forces autovivifying of that undef value into a hash ref, to provide write access. How to verify? "Use the source, luke." ;-)

      That's the sad thing about perl5 - the implementation is the spec. But then it is also its glory, as Abigail puts it:

      Programming in Perl5 is like exploring a large medieval castle, surrounded by a dark, mysterious forest, with something new and unexpected around each corner. There are dragons to be conquered, maidens to be rescued, and holy grails to be quested for. Lots of fun.

      I'll have a bit of fun, when I have time to spend...

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}