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

hi, I am running the following code:

use strict; use warnings; my $newvar=0; if (defined $undefvar) { $newvar = $undefvar; }

and getting the following error:

Global symbol "$undefvar" requires explicit package name at C:\Users\l +iorlew\Desktop\perl\fixes\scripts\test.pl line 5. Global symbol "$undefvar" requires explicit package name at C:\Users\l +iorlew\Desktop\perl\fixes\scripts\test.pl line 7.

this is not the first time I used this functionality, but I do not seem to find what is wrong with the code.

Thank you,

Lior

Replies are listed 'Best First'.
Re: if defined not working
by choroba (Cardinal) on Feb 04, 2016 at 15:45 UTC
    Hi liorlew, welcome to the Monastery!

    Under strict, or more precisely, strict 'vars' , you have to declare each variable before you use it. You haven't declared $undefvar .

    use strict; use warnings; my $newvar = 0; my $undefvar; # Declared, but undefined. if (defined $undefvar) { $newvar = $undefvar; }

    Update: refsvars

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: if defined not working
by stevieb (Canon) on Feb 04, 2016 at 15:47 UTC

    Welcome to the Monastery, liorlew!

    You have use strict; enabled, so that's fantastic (we always recommend that, along with use warnings;). The thing is, strict is signalling an error because, just like the error states, you haven't declared your variable $undefvar. Undefined means it hasn't been assigned to yet, undeclared means you haven't mentioned it at all, and perl doesn't allow this under strict.

    One of the reasons it does this is to prevent typos when coding. It's likely that after you get used to strict and you get this error, you've probably mistyped a variable name. This is a lot better than letting the script blindly run along, producing weird errors possibly somewhere far away from where the problem really is.

    This will fix it:

    use strict; use warnings; my $newvar=0; my $undefvar; # we declare, but do not define if (defined $undefvar){ $newvar = $undefvar; } # $newvar still 0, because $undefvar has been declared, # but not defined with a value print "$newvar\n";

    See strict.

Re: if defined not working
by Athanasius (Archbishop) on Feb 04, 2016 at 16:02 UTC

      Hi Athanasius,

      I'm curious, what in your view is the advantage of using Logical Defined-Or over simple Logical Or in the OP's situation?

      $ perl -Mstrict -Mwarnings -E' my $foo; say (defined $foo ? "1: defined" : "1: not defined"); my $bar = $foo; say "2: bar: $bar"; my $baz = $foo || "baz"; say "3: baz: $baz"; my $qux = $foo // "qux"; say "4: qux: $qux"; ' 1: not defined Use of uninitialized value $bar in concatenation (.) or string at -e l +ine 5. 2: bar: 3: baz: baz 4: qux: qux

      Thanks!

      The way forward always starts with a minimal test.

        Hey Nick,

        The difference really only matters if what you're checking has a false value (that you may not know about, such as when looping through a hash). A false value is still defined:

        perl -wMstrict -E 'my $x=0; say $x||1; say $x//2;' 1 0

        Update: here's a tiny example that shows that in a larger application, not checking for defined can be an issue when you aren't explicitly looking for truth:

        use warnings; use strict; this(arg => 0); sub this { my %args = @_; do_something("if\n") if $args{arg}; do_something("if def\n") if defined $args{arg}; } sub do_something{ print shift; }
        my $one = 1; my $zero = 0; my $undef; my $result; $result = 1; # 1 $result = 1 || 0; # also 1 $result = 0 || 1; # also 1 $result = $zero || $one; # also 1 $result = $zero // $one; # 0 $result = $zero // 1; # 0 as well $result = 0 // 1; # 0 as well $result = $undef // $one; # 1 again $result = $undef || $one; # 1 again $result = fork || die; # dies in the child process or if failing to + fork $result = fork && die; # dies in the parent process $result = fork // die; # dies in process unable to fork a child # (beware the return values of function calls, for they are subtle and + quick to bite your behind)