in reply to Confusion over scope of "my" vars

I have an interpretation for your results but no time for a formal proove.

At compiletime the pads for the lexicals $x and $y are associated to the sub. With a recursiv call perl has to allocate a new pad for the function, instead of reusing the old one.

Furthermore the if-branches are optimised away, so no "my $x" is executed at runtime to resetting $x to undef, so your accessing in 2 and 4 the last setting in the same level.

in short, it's one of these strange side effects of optimising code away, using B:Deparse you will most probably code-chunks missing.

you can also try this, which results in an error

goto label; if (0) { label: print "huhu"; }
(untested)

so be aware of optimised code-chunks.

Replies are listed 'Best First'.
Re^2: Confusion over scope of "my" vars
by LanX (Saint) on Nov 26, 2008 at 18:20 UTC
    ups I wasn't logged in...

    UPDATE: you may want to use B::Deparse and B::Concise and the debugger to see what actually happens!

    Anyway I'm not sure why perl doesn't reset the lexical pad to undef when leaving the sub, might be a bug or a necessity for closures.

    If I were you, I'd report this code to perlporters most likely they already discussed it!

    > you can also try this, which results in an error

    I know it's documented but I'm not happy about this behaviour!

      Anyway I'm not sure why perl doesn't reset the lexical pad to undef when leaving the sub
      Well, that's quite obvious. "Resetting" variables that go out of scope would be waste of resources. You'd spend time setting a value for a variable that has no references to it left.

      What's the point?

        > What's the point?

        Obviously the allocated space is reused, leaving it in a defined state is maybe faster and works in 99.9% of all cases but is nevertheless *dirty*.

        And an extra opcode "ResetPad" realised in C can't be too expensive in comparison to the overall overhead of function calls.

        Cheers Rolf

        UPDATES:

        1. Only if the reference counter is 0, then clearing the PAD only means supporting the garbage collection.

          (The reference counter is not neccessarily 0 at the end of the scope)

        2. hmm actually whenever the reference counter is decremented to 0 it might be the best occasion to set the variable to undefined, this would lead to a very consistent behaviour.

        3. I have to admit that some people might interpret this behaviour as a feature! I mean if noninitialised lexvars act like closuresvars, but only teh sub is in the same level of recursion! One might even calculate the level of recursions...spooky! But I bet this behaviour is not guaranteed! 8 )