http://www.perlmonks.org?node_id=1203128

dave741 has asked for the wisdom of the Perl Monks concerning the following question:

#!/usr/local/bin/perl use strict; foreach my $name ('A', 'B') { my $res = 'Init' if (0); if (defined ($res)) { print "$name: res = $res\n"; } else { print "$name: res is undef\n" } $res = 'Post'; }

Result:
A: res is undef
B: res = Post


As $res is under lexical variable scope, shouldn't it disappear at the bottom of the block
and be recreated by the second pass, producing an identical result?
Bug? Feature? Saving CPU?

perl -v
This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi

Thoughts?
Dave

Replies are listed 'Best First'.
Re: Variable Scope (updated)
by haukex (Archbishop) on Nov 10, 2017 at 16:55 UTC

    From perlsyn:

    NOTE: The behaviour of a my, state, or our modified with a statement modifier conditional or loop construct (for example, my $x if ...) is undefined. The value of the my variable may be undef, any previously assigned value, or possibly anything else. Don't rely on it. Future versions of perl might do something different from the version of perl you try it out on. Here be dragons.

    Update: Heh, Eily and I posted within 4 seconds of another ;-)

    Update 2: Historically, sometimes this "feature/bug" was (ab)used to make variables "static", just two references of many found with a quick search: Unusual Closure Behaviour, Re: Making a variable in a sub retain its value between calls. The better ways to do this are described in Persistent Private Variables:

    BEGIN { my $static_val = 0; sub gimme_another { return ++$static_val; } } # - OR - in Perl >=5.10: use feature 'state'; sub gimme_another { state $static_val = 0; return ++$static_val; }

    But nowadays, anywhere you see the pattern, it should be considered a bug, see "Using my() in false conditional" in perldeprecation. On Perl 5.26:

    $ perl -e 'my $x if 0' Deprecated use of my() in false conditional. This will be a fatal erro +r in Perl 5.30 at -e line 1.

    Update 3: Apparently, the warning "Deprecated use of my() in false conditional" first showed up in Perl 5.10 and became a default warning in 5.12. Note that your Perl 5.10.1 is now more than eight years old, and you should upgrade. Also, you should generally use warnings; (Use strict and warnings).

Re: Variable Scope
by Eily (Monsignor) on Nov 10, 2017 at 16:55 UTC

    According to perlsyn:

    NOTE: The behaviour of a my, state, or our modified with a statement modifier conditional or loop construct (for example, my $x if ... ) is undefined. The value of the my variable may be undef, any previously assigned value, or possibly anything else. Don't rely on it. Future versions of perl might do something different from the version of perl you try it out on. Here be dragons.
    So neither bug nor feature, third option.

Re: Variable Scope
by AnomalousMonk (Archbishop) on Nov 10, 2017 at 17:07 UTC

    See the state feature from Perl 5.10 onward for similar "static variable" behavior that is well-defined.


    Give a man a fish:  <%-{-{-{-<