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

I'm experiencing a scope problem that I can't figure out. I'm using warnings, and I get the following warning: "Use of uninitialized value $f1missing in numeric eq (==) at C:\scripts\DailyComp2.7.pl line 520 (#1)" At this point in the script, I'm using NET::Telnet and I'm in a telnet session. Here's the chunk of code that's producing the warning:

# Check for error that first input file can't be found my $f1missing = 0; $f1missing = $t->waitfor(String => 'That file is unavailable', errmode => 'return'); if ($f1missing == 1) { print "\nFirst input file $prevcomp is missing!!\n"; $t->print(); # Send Enter for prompt $t->print(); # Send Enter to exit COMPARE $CTYPE = 0; # Set Compare type back to 0 to avoid running COMPARE r +eport again $ETYPE = 1; # Set error type to 1 return; # Exit subroutine }

I initialize the value right before I use it in the if function, so why would it produce an uninitialized value warning here? As always, any help would be appreciated.

Replies are listed 'Best First'.
Re: Scope Issue
by Corion (Patriarch) on Mar 15, 2011 at 12:43 UTC

    You initialize it, and then overwrite that value again with the result of $t->waitfor(...). And that result is likely undef. You can use defined to check for undef without warnings.

Re: Scope Issue
by AR (Friar) on Mar 15, 2011 at 13:02 UTC

    If you're using Perl 5.10 or greater, you can also use the defined or operator:

    my $f1missing = $t->waitfor(String => 'That file is unavailable', errmode => 'return') // 0;

    What the code above does is similar to what Corion suggested. It tests whether the result is defined, and will substitute with 0 if it is not.

      Am I wrong or did you mean || instead of //?

        // is the defined or operator. || is the or operator. // and //= were added in in 5.10 as a shortcut for something along the lines of $var = defined $var ? $var : $default_value;

        $var //= $default_value; is much prettier IMHO. I'm fairly certain // and || short-circuit in the same exact way. It's easy enough to test.

        || is the regular or operator ("true, or ..." you might say).

        // is the defined or operator ("defined, or ...").

      Thanks, AR. That worked - the warning went away.

        I have another question on this topic. I'm also getting a similar warning in another part of the code: "Use of uninitialized value $\ in concatenation (.) or string at C:\scripts\DailyComp2.8.pl line 208 (#1)". This warning comes from the following line of code:

        my $match_live = "\/LIVE>.*$\/";

        I am defining a pattern match for Net::Telnet to use in various places in the code. The back slash in $\ is there to escape the forward slash which is the end of the pattern match, but it looks like PERL is interpreting it as variable. Any suggestions? Thanks