3

The following code will return an error,

$ perl -E'sub foo { my $bar if 0; $bar++ }'
This use of my() in false conditional is no longer allowed at -e line 1.

But this code

$ perl -E'sub foo { my $bar = undef if 0; $bar++ }'

Does not return an error. Is there any difference between these two forms?

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
  • 1
    "Undefined behavior" in the second case, so broken code. (The first one is outright bizarre -- how could one conditionally _declare_ a variable?) – zdim Sep 23 '20 at 23:18
  • @zdim It's conditionally declared in the second as well. People used it as a hack to get a `state`-like effect. – ikegami Sep 23 '20 at 23:31
  • 1
    @ikegami Sure. But in the second case at least _the intent appears to be_ that the assignment is conditioned. (As for an actual "difference", the question itself shows one -- in how the code is processed. Otherwise, of course, both have the same problem of "mixing" compile-time and run-time effects.) I didn't know of such use of it though! – zdim Sep 23 '20 at 23:43

1 Answers1

7

my has a compile-time effect and a run-time effect, and you don't want to use a my variable without first having its run-time effect.

Since the problematic situation is using a my variable under different conditions than it was declared, there is no difference between your two snippets. Both should be avoided.

To create a persistent variable scoped to a sub, you can use

{
   my $bar = 0;
   sub foo {
      return $bar++;
   }
}

or

use feature qw( state );  # 5.10+

sub foo {
   state $bar = 0;
   return $bar++;
}
ikegami
  • 367,544
  • 15
  • 269
  • 518