

Interesting Perl Behavior - dangoldin
http://www.dangoldin.com/blog/2008/05/30/interesting-perl-behavior/

======
jrockway
This has been well-known for years. People have used it for things like:

    
    
       sub increment {
          my $counter = 0 if 0;
          ++$counter
       }
    

It works the same way as:

    
    
       {
          my $counter = 0;
          sub increment { ++$counter }
       }
    

It's actually a combination of various bugs that makes it work, so you
shouldn't rely on the behavior. But since people have been relying on the
behavior for years, it probably won't go away any time soon.

Perl 5.10 has a keyword ("state") for declaring this sort of variable
explicitly, though, so there's no reason to use this pattern in new code.

------
jm4
What's interesting about this? There's a big, bold note in the documentation
that says the result of this usage of a statement modifier is undefined, and
that's exactly what happened.

I guess it's nice that the blog author is giving everyone a heads up, but this
shouldn't be news to anyone who actually reads the documentation for the tools
they use.

~~~
dangoldin
I just found it interesting because when I wrote the initial code I assumed it
would work they way that seemed more intuitive to me. After I encountered that
I went into the documentation to investigate but I don't think that one should
be expected to read every single piece of documentation, least of all in a
seemingly trivial case like this.

~~~
mst
It's a -sort of- bug.

perl 5.10 actually throws a warning when you trip it, and provides a 'state
$x' keyword that provides the same functionality as 'my $x if 0' safely.

The basic problem is that the 'my' causes a lexical pad entry to be generated
at compile time, but because the if 0 prevents the statement running at
runtime it doesn't get reinitialised on your way round the loop.

(I've also made this comment on your blog, but it's the sort of thing people
should manage to find easily so I figured it'd be ok to duplicate it)

~~~
dangoldin
Yea no worries, the more people that learn this the better - it took me a bit
to diagnose. That was basically my understanding. It looks like the scope of
the my gets a bit weird with that if(0) there.

------
rbanffy
Like I said there, it looks like "(my if (0)) $var = 0" is happening.

It would be interesting to run some other tests.

~~~
philh
A simple test is to check $val outside of the sub - it isn't defined. (Compile
error with strict vars, runtime error otherwise.)

------
snorkel
Conditional lexical scoping sounds like a recipe for disaster anyway.

