Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to pass a parameter outside of my loop but it says I can not do this.
use strict; my $mydir = "/path/paths"; my $bool = 0; opendir(DIR, $mydir) || die "Can not open $mydir: $!\n"; while (my $file = readdir(DIR)) { if($file =~ /^myname\.doc$/i) { $bool = 1; } } closedir(DIR); if($bool) { print "$file"; }
My error message:
Global symbol "$file" requires explicit package name at C:\Perl\bin\sc +rp.pl line 22. Execution of C:\Perl\bin\scrp.pl aborted due to compilation errors.

Replies are listed 'Best First'.
Re: Passing value outside of loop
by davorg (Chancellor) on Jan 07, 2003 at 16:32 UTC

    You create a lexical variable called $file that exists within the scope of your while loop. Once the while loop terminates, that scope disappears and the that variable ceases to exist. You then try to access another variable called $file. As there is no lexical variable of that name in existance, Perl assumes that it is a package variable. But as you have "use strict" turned on, you need to either predeclare or explicitly name any package variables that you use. As you have done neither of these two things, you get the error you've shown us.

    The solution to your problem would be to create the lexical variable $file outside of the loop, so that it doesn't just exist within that scope.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Passing value outside of loop
by hardburn (Abbot) on Jan 07, 2003 at 16:33 UTC

    my() creates a variable in the current lexical scope. Since the "my $file" is in the while loop's condition, $file is created in the while loop and then goes away. Try this:

    my $file; while($file = readdir(DIR)) { ...

    Also, unless you have a bunch of other code in the while loop that needs to run, you should exit the loop once $bool becomes true (BTW--$bool is a really lousy name for a variable). Additionally, it is usually good practice in a regex match to use '^' and '$' to indicate line beginnings/ends, and '\A' and '\z' to indicate string beginnings/ends. This is not a strict requirement, and you'll usually be OK if you switch them around.

    my $file; while ($file = readdir(DIR)) { if($file =~ /\Amyname\.doc\z/i) { $bool = 1; last; } }
Re: Passing value outside of loop
by FamousLongAgo (Friar) on Jan 07, 2003 at 16:36 UTC
    You're declaring the variable within the lexical scope of the while block, so it goes out of scope by the time you reach the conditional.

    Try this instead:

    my $found; while ( my $file = readdir(DIR) ){ $found = $file, last if $file=~/^myname\.doc$/i; } closedir(DIR); print "Found: $found" if $found;

      Thank you to all.
Re: Passing value outside of loop
by thewalledcity (Friar) on Jan 07, 2003 at 16:36 UTC
    I believe that your variable $file is only available inside the while loop because of scope (someone feel free to correct me if I'm mistaken). You should put the my $file before the start of the while loop.
Re: Passing value outside of loop
by Arien (Pilgrim) on Jan 08, 2003 at 08:04 UTC

    That's a lot of code just to see if there's a file $file in $dir. Use Perl's file tests:

    my $dir = "/path/paths"; my $file = "myname.doc"; print "Found '$dir/$file'.\n" if -f "$dir/$file";

    — Arien