John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

I happened to notice this in a working script as I was about to make changes. Now I'm afraid to touch it!

The variable $database is defined via my inside an if statement. Why can code outside of that block refer to it?

The closure that uses it should not be able to see into a parallel scope, as it only sees its enclosing things, right? Is there something funny about if statement blocks, or is this a perl bug, or what? The code works, and it's clear that the $database used by the subsequent code indeed is connected to Source Safe, so it's not finding a stray global.

baffled,
—John

Update: it no longer compiles, but gives the expected error. So why did it work once, on November 21? I hate anomolies.

Code attached,

sub go { print "Working area is \"$directory\"\n"; $version_text= "Iteration $version[0], " . ($version[2] ? "Revision $version[2]" : "initial release") . ($version[3] ? ", Patch $version[3]" : ""); print "Version stamp: $version_text\n"; if ($option eq 'checkout') { my $database; ###### DECLARE HERE $database= new Win32::OLE:: "SourceSafe"; my $copy= $source_safe_repository; # OLE doesn't like magic varia +bles $database->Open ($copy); } my $eachfile= sub { # on entry, $_ is name alone return unless /\.cxx$/ || /\.cpp$/ || /\.h$/ || /\.hpp$/; my $fname= $File::Find::name; $fname =~ tr[/][\\]; eval { process_file ($fname, $database); ##### USE HERE }; if ($@) { print "* An error was encountered processing \"$fname\". Error t +ext is:\n$@\n"; } }; my $filter= sub { return grep {$_ ne "Dependant_Libs" && !/\.OUT\./} @_; }; find ({wanted => $eachfile, preprocess => $filter}, $directory); print '=' x 50, "\n"; }

Replies are listed 'Best First'.
Re: Something fishy about my scope
by sauoq (Abbot) on Dec 10, 2002 at 20:39 UTC
    The code works, and it's clear that the $database used by the subsequent code indeed is connected to Source Safe, so it's not finding a stray global.

    Is it possible that $database is a stray global that also happens to be connected to Source Safe?

    P.S. This was post 500. I was going to save it for something somehow more profound but I didn't.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Something fishy about my scope
by dws (Chancellor) on Dec 10, 2002 at 20:44 UTC
    The variable $database is defined via my inside an if statement. Why can code outside of that block refer to it?

    That looks very wrong, and (assuming there isn't a stray global named $database) I'm not able to replicate the behavior using 5.6.1. What version of Perl are you using?

Re: Something fishy about my scope
by Willman023 (Scribe) on Dec 10, 2002 at 21:01 UTC
    If you look here the perldoc says, "my($x) creates a new variable x that is only visible in the current subroutine." So assuming that the if statement block is in the same subroutine, I believe $database is still local.

    bW

      Don't believe everything you read. That simply isn't a very good explanation of my() and lexical variables. Lexical variables are visible only in their enclosing file, block, or eval.

      -sauoq
      "My two cents aren't worth a dime.";