Lexical scope of my

perl

Solution

The `my` doesn't take effect until the end of the statement.

For that same reason, `my $x = $x` won't see the new `$x` on the right hand side of the statement. It'll see the old `$x`.

For example

use strict;
use warnings;

my $x = 42;

{
    my $x = $x + 1;
    print "inside, x = $x\n";
}

print "outside, x = $x\n";

This prints:

inside, x = 43
outside, x = 42

Your `open` statement is roughly equivalent to the inner `my` statement above. If you had `$fh` declared in the outer scope, surprising fun would happen: You'd probably end up printing to the wrong file.

Problem

Pretty much every perl program written uses this idiom: ``` { open(my $fh, '>>', $filename) || die "you lose"; print $fh $blah; } ``` However, I don't want to die, I want to just skip the print. So I write: ``` { print "you lose\n" unless (open(my $fh, '>>', $filename) and print $fh $blah); } ``` and get "Can't use an undefined value as a symbol reference at ./o.pl line 5" for my trouble. Removing the my (bad form) eliminates this error, as does: ``` { my $fh; print "you lose\n" unless (open($fh, '>>', $filename) and print $fh $blah); } ``` but why? Why, in the broken code, doesn't `$fh` exist from `open(my $fh...` to the close of the block (the `}`)?

Original source