What is happening when my() is conditional?

perl

Solution

You can think of a `my` declaration as having an action at compile-time and at run-time. At compile-time, a `my` declaration tells the compiler to make a note that a symbol exists and will be available until the end of the current lexical scope. An assignment or other use of the symbol in that declaration will take place at run-time.

So your example

my $c = 1 if 0;

is like

my $c;         # compile-time declaration, initialized to undef
$c = 1 if 0;   # runtime -- as written has no effect

Note that this compile-time/run-time distinction allows you to write code like this.

my $DEBUG;    # lexical scope variable declared at compile-time
BEGIN {
    $DEBUG = $ENV{MY_DEBUG};   # statement executed at compile-time
};

Now can you guess what the output of this program is?

my $c = 3;
BEGIN {
    print "\$c is $c\n";
    $c = 4;
}
print "\$c is $c\n";

Problem

Compare using `perl -w -Mstrict`: ``` # case Alpha print $c; ``` ... ``` # case Bravo if (0) { my $c = 1; } print $c; ``` ... ``` # case Charlie my $c = 1 if 0; print $c; ``` `Alpha` and `Bravo` both complain about the global symbol not having an explicit package name, which is to be expected. But `Charlie` does not give the same warning, only that the value is uninitialized, which smells a lot like: ``` # case Delta my $c; print $c; ``` What exactly is going on under the hood? (Even though something like this should never be written for production code)

Original source