in reply to Unusual Closure Behaviour

$x should dissapear when it leaves the scope of foo. Why isn't this happening? Seems like the table is keeping it. If you take out the if undef the variable keeps on being redefined and reset. Could be useful for recursion :)


Replies are listed 'Best First'.
Re: Re: Unusual Closure Behaviour
by HyperZonk (Friar) on Jul 12, 2001 at 17:34 UTC
    $x should not disappear outside the scope of foo. my $x if undef; means that $x is not local; the my, though noted at compile time (mainly to prevent strict complaints), does not actually produce a scoping effect until run-time (if I understand the perldocs correctly). Therefore, the my $x is never evaluated for scoping purposes, since undef is always false.
      HyperZonk and Synapse0 have both suggested that the my is being ignored and all that is happenning is that $x is simply global.

      It's a good theory, and certainly what I thought when I first looked at it. But it's easy to see that this isn't true: try comparing

      sub foo{ my $x if 0; print "FOO: ", $x++, "\n"; } sub bar{ my $x if 0; print "BAR: ", $x--, "\n"; } foo, bar for (1..10);
      sub foo{ print "FOO: ", $x++, "\n"; } sub bar{ print "BAR: ", $x--, "\n"; } foo, bar for (1..10);

      I reckon the real reason is the explanation given by Abigail.

      Now I don't think I would ever write my $x if 0 unless I wanted to get the sack for writing obscure code, but how about:

      sub STATIC_VARIABLE{ 0 } sub foo{ STATIC_VARIABLE && my $x; print "FOO: ", $x++, "\n"; }
      would that be difficult to understand? Would it carry on working in the future?

      -- iakobski

        Obscure stuff indeed. I think that Abigail was indeed correct. I suppose I should have actually tested my hypotheses in code, like you did. <blush>

        It seems that, despite what the perlref docs seem to say, the scoping of the variable is done at compile time, but the variable's reinitialization is done at run-time. Well, I guess we should expect at least the first since it is a lexical, right?

        In any case, because of the compile-time scoping, we end up with a local via my no matter if the line in which it is declared will ever run or not. But the initialization never runs because of the permanently false conditional at the point at which the run-time must run initialization code. Actually, I suspect that we should expect this behavior because data scoping is easily done at compile, but initialization must be done at run-time.

        Now, I think that this could be considered a feature for those savvy to this rather bizarre behavior. And I like the recommended usage from iakobski. But I would put a comment in at the STATIC_VARIABLE declaration, in case the script needs to be maintained by a non-monk.