in reply to Hash value test of zero

As others have said, always use warings; use strict;

When you do a math operation, == or +/- etc, Perl will convert a string value to a numeric value according to its rules. Trying to use a string that does not exactly represent a number as a number causes a warning with one exception shown below.

Here is some example code:

use strict; use warnings; $|=1; #turn off stdout buffering so error msgs match my $x = "awsdfasdf"; print "zero\n" if ($x==0); # zero #Argument "awsdfasdf" isn't numeric in numeric eq (==) $x+= 0; print "x\n"; #0 my $y="asdf6"; #ending digits to alpha do not count $y+= 0; #Argument "asdf6" isn't numeric in addition (+) print "$y\n"; #0 my $z = "3asdf"; #beginning digits will be used $z+=0; #Argument "3asdf" isn't numeric in addition (+) print "$z\n"; #3 my $x1 = "0 but true"; #more common now is 0E0 $x1+=0; # NO ERROR! print "$x1\n"; #0 my $x2 = "3 camels"; #can have textual "units" $x2+=0; #Argument "3 camels" isn't numeric in addition (+) print "$x2\n"; #3 __END__ Argument "awsdfasdf" isn't numeric in numeric eq (==) at line 7. zero x Argument "asdf6" isn't numeric in addition (+) at line 14. 0 Argument "3asdf" isn't numeric in addition (+) at line 20. 3 0 Argument "3 camels" isn't numeric in addition (+) at line 31. 3
As the above code shows the "0 but true" exception is hard-coded into Perl as an exception. This allows a function to return a single value that can represent both logically true and numerically zero. Using that string as a numeric value will not cause a warning. This is now seldom seen as the exponential value 0E0 is more commonly used, especially by the DBI.

Replies are listed 'Best First'.
Re^2: Hash value test of zero
by eyepopslikeamosquito (Archbishop) on Jul 26, 2023 at 10:30 UTC

    As the above code shows the "0 but true" exception is hard-coded into Perl as an exception. This allows a function to return a single value that can represent both logically true and numerically zero. Using that string as a numeric value will not cause a warning. This is now seldom seen as the exponential value 0E0 is more commonly used, especially by the DBI.

    Interesting. From perlop:

    Perl operators that return true or false generally return values that can be safely used as numbers. For example, the relational operators in this section and the equality operators in the next one return 1 for true and a special version of the defined empty string, "", which counts as a zero but is exempt from warnings about improper numeric conversions, just as "0 but true" is.

    In my experience, this is well-known ... well much better known than the quirky dualvar ... which caused a sensation here recently when uncorked by marioroy during the long running Long List is Long saga. Mario is the only Perl programmer I know who has used dualvar in production code (in MCE::Shared::Cache part of MCE).

    See also:

      That perlop quote is a little out of date. It's not wrong per-se, but the boolean values returned by most operators are now more succinctly described as builtin::true and builtin::false.

        Interesting. First time I've heard of builtin::true and builtin::false ... I see perldoc builtin warns:

        The overall builtin mechanism, as well as every individual function it provides, are currently experimental

      Mario is the only Perl programmer I know who has used dualvar in production code

      Well now you know two, because I delight in using dualvars for XS constants :-)

      use Fluent::LibFluentBit qw( FLB_LIB_NO_CONFIG_MAP ); say FLB_LIB_NO_CONFIG_MAP; say 0+FLB_LIB_NO_CONFIG_MAP;
      Output:
      FLB_LIB_NO_CONFIG_MAP 2

      The great part is that when you pass them to XS functions, they pass the integer that XS is looking for, and when you dump those parameters to STDOUT or a logger, you get the constant name so you can understand what is going on.