Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Perl think "0 but true" is a number? [duplicate]

Can someone explain what exactly the string "0 but true" means in Perl? As far as I understand, it equals zero in an integer comparison, but evaluates to true when used as a boolean. Is this correct? Is this a normal behavior of the language or is this a special string treated as a special case in the interpreter?

like image 426
jkramer Avatar asked Sep 24 '08 21:09

jkramer


People also ask

Is 0 true in Perl?

False Values: Empty string or string contains single digit 0 or undef value and zero are considered as the false values in perl.

What is 0 in Perl?

Perl has a number of values that are considered "false": undef , zero, the string "0" , the empty string, a special boolean value that morphs into the empty string or the empty list depending on context, and objects that are overloaded for boolean context.


2 Answers

It's normal behaviour of the language. Quoting the perlsyn manpage:

The number 0, the strings '0' and "", the empty list (), and undef are all false in a boolean context. All other values are true. Negation of a true value by ! or not returns a special false value. When evaluated as a string it is treated as "", but as a number, it is treated as 0.

Because of this, there needs to be a way to return 0 from a system call that expects to return 0 as a (successful) return value, and leave a way to signal a failure case by actually returning a false value. "0 but true" serves that purpose.

like image 72
Chris Jester-Young Avatar answered Sep 22 '22 17:09

Chris Jester-Young


Because it's hardcoded in the Perl core to treat it as a number. This is a hack to make Perl's conventions and ioctl's conventions play together; from perldoc -f ioctl:

The return value of ioctl (and fcntl) is as follows:

if OS returns:      then Perl returns:      -1              undefined value      0              string "0 but true" anything else       that number 

Thus Perl returns true on success and false on failure, yet you can still easily determine the actual value returned by the operating system:

$retval = ioctl(...) || -1; printf "System returned %d\n", $retval; 

The special string "0 but true" is exempt from -w complaints about improper numeric conversions.

like image 29
geekosaur Avatar answered Sep 21 '22 17:09

geekosaur