views:

114

answers:

2

Is it safe/good practice in Perl to use an empty string as false in boolean comparisons?

ex:

my $s = '';

if($s) {
 print 'true';
} else {
 print 'false';
}

or would the length function be a better way to go:

my $s = '';

if(length($s) > 0) {
 print 'true';
} else {
 print 'false';
}
+5  A: 

A string can have length but still be false -- specifically, the string '0' (details: Perl Truth and Falsehood). At least in the general case, length does not provide a robust test for truth.

my $s = '0';

print "'0' is false.\n"      unless $s;
print "But it has length.\n" if length $s;

Typically, you should use the test the characteristic that expresses what you really care about. For example, if you ask a user to enter his favorite age, '0' is a false but valid response: "My first year of life was great, and then everything went to hell."

FM
+7  A: 

When testing for true/false in an expression, you should think carefully about what you actually want to test.

If you have a string and you need to check if it has any value at all, then test for that:

if (defined $string) { ... }

If you are passing back a "boolean" value from a function, or testing the result of some internal operation, then perform a boolean check:

if ($value) { ... }

In Perl, "truth" depends on the manner in which it is evaluated. If you simply say if ($value), then the only string values that evaluate to false are the empty string '', and a literal zero '0'. (Also, any undefined value is false, so if $value has never been assigned, that would be false too.)

There are other values which may evaluate to false in a numerical context, for example 0E0, 0.0000, and the string '0 but true'. So the question "what is truth" really depends on the context, which you the programmer need to be aware of.

Internally, Perl uses '' for false and 1 for truth (for example as the result of any boolean expression such as !$value). A common technique for "canonicalizing" any value into one of these two values is !!$value -- it inverts a value twice, giving you either '' or 1.

Ether
its worth also mentioning the various casting operators are useful when checking for truth. in particular, the double negation `!!` will always convert a value into a valid boolean
Eric Strom
@Eric: I think you added that comment right while I was adding my last sentence :D
Ether