in reply to Unforgettable Closures?

Quoting perlsyn:

NOTE: The behaviour of a my statement modified with a statement modifier conditional or loop construct (e.g. 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.
I thought this "feature" had been removed in the upcoming 5.10 release of perl, but I can't find any reference to it now :(

update

Gah! I was reading perl595delta instead of perl5100delta:

New or Changed Diagnostics

...

Deprecated use of my() in false conditional
A new deprecation warning, Deprecated use of my() in false conditional, has been added, to warn against the use of the dubious and deprecated construct

    my $x if 0;

See perldiag. Use state variables instead.

Replies are listed 'Best First'.
Re^2: Unforgettable Closures?
by syphilis (Archbishop) on Dec 09, 2007 at 12:42 UTC
    Gah! I was reading perl595delta instead of perl5100delta

    Is perl5100delta relevant here ?

    I mean ... the code provided by the op produces the same output on both 5.8.8 and 5.10.0 (for me, anyway):
    1,2,3 at try.pl line 22. my func is funky!
    Cheers,
    Rob
      I hadn't tried it earlier, but I get the same here with 5.10.0, with & without warnings. It appears that Deprecated use of my() in false conditional applies only in limited cases:

      my $x if 0; #warns my $x if ""; #warns my $x if undef; #OK my $x = 0 if 0; #OK
      Test program used:

      use warnings; sub a { my $x = 0 if undef; print ++$x } a for 1 .. 3;

Re^2: Unforgettable Closures?
by faiz (Acolyte) on Dec 10, 2007 at 00:55 UTC
    Oh boy, Occam's razor. Thanks, that clears it up, I guess. I've not got anything newer than Perl 5.8.8, and grepping perlsyn for the said gotcha finds nothing, so I'm assuming I need a newer Perl?

      No, you don't need a newer version of Perl (it wouldn't help you, for several reasons1).

      You need to change your code that looks like:

      my $var= ... if ...;

      to instead look like

      my $var; $var= ... if ...;

      You don't want to skip the run-time effect "my" when your conditional is false. That run-time effect is what resets your variable so that you don't get a previous value.

      - tye        

      1 A) The newer version just adds warning; it doesn't change how anything works. B) The warning doesn't even apply to what you've done; it appears this new warning is pretty stupid, in fact. C) Just fix your code and it works fine on old versions of Perl.

        (shave)
        hehe. Yeah, Occams Razor because of my mistaken assumptions (closure funkiness versus perlsyn (my) funkiness). Me:
        Thanks, that clears it up, I guess. I've not got anything newer than Perl 5.8.8, and grepping perlsyn for the said gotcha finds nothing, so I'm assuming I need a newer Perl?
        I meant new version of Perl for which the man page for perlsyn mentions the "my" strangeness. I ought to have mentioned it, but before I'd reproduced the funkiness on my local 5.8.8 installation, I came across it on (sigh) 5.6.1 - on which the following fix worked:
        Well whatever the reason is, the fix was simply:
        #my $func = shift if ref $_[0] eq 'CODE'; my $func = ref $_[0] eq 'CODE' ? shift() : undef;
        Of course, as you rightly point out, separating the "my" and the conditional also works, like you point out.
        my $func; $func = shift if ref $_[0] eq 'CODE';
        all good! Thanks.