Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some string values ("0", "", and " ") are defined, but (==undef)

Tags:

perl

undef

In my perl script, I used if ($a == undef) condition, I thought it is the same as if (not defined $a), where $a is a string as read from a csv file. However, I noticed that several string values ("", " ", "0", "-0", "+0", "@", "a", and many other spaces and special characters) are defined but also undef. If undef is only for numeric values, it should pass "0", "+0", and "-0". Can anyone explain? I understand now that I should not use if ($a == undef) to replace if (not defined $a).

My testing code is:

@a_array = ("-1", "-0", "0", "+0", "1", "", " ", "@", "a", "\$", "-");
undef $a;
test_a();

foreach $a (@a_array) {
    $len_a = length($a);
    test_a();
}

sub test_a {
    if (defined $a) { print "a = $a is defined;  "} else {print "a = $a not defined; "}; 
    if ($a == undef) { print "a = $a (== undef);  "} else {print "a = $a (!= undef); "}; 
    if (length($a) > 0){ print "length of a is $len_a > 0 \n"} else {print "length of a is $len_a !> 0 \n"};
}
like image 634
Douglas Avatar asked Feb 06 '20 22:02

Douglas


1 Answers

Perl has two equality operators: == and eq. == tests if the numeric form of each value is numerically equal. eq tests if the string form of each value is lexicographically equal. undef is not a string or a number, and if used as a string it is equivalent to the empty string, if used as a number it is equivalent to 0 (as is the empty string, and any string that doesn't start with something that looks like a number). You usually get warnings when this happens.

To test for undef, no equivalence test should be involved: use the defined function. Only if it is defined can it have a meaningful string or number value, and you can do subsequent tests.

The length function returns undef when passed undef, so if you want to know if a scalar is both defined and not length 0, you only need one boolean check: if (length $x). 0 and undef are both false results. Note that before Perl 5.12 this would cause a warning, as length undef attempted to use undef as a string, like eq does.

like image 115
Grinnz Avatar answered Oct 21 '22 10:10

Grinnz