On Wed, Jul 28, 2010 at 11:21:31AM -0400, Chas. Owens wrote: > I took a [quick look][0] to see how well documented "0 but true" is. > It looks like it is only mentioned tangentially. Similarly, "0E0" gets > mentioned once in perlop: > > The final sequence number in a range has the string "E0" appended to it, > which doesn't affect its numeric value, but gives you something to search > for if you want to exclude the endpoint. > > They should probably be documented in the [Truth and Falsehood][1] > section of perlsyn. A patch will be forthcoming. Does anybody know > the full list of strings that are not warned about? I know that > strings that match the following regex are all true but do not warn in > numeric context: > > my $zero_but_true = qr{ > \A > \s* > (?: > 0 but true | # "0 but true" > 00+ | # "00", "000", etc. > 0+[.]0* | # "0.", "00.00", etc. > [.]0+ | # ".0", ".0000", etc. > 0+[eE][0-9]+ | # "0e0", "00e19", etc. > 0+[.]0*[eE][0-9]+ | # "0.e0", "000.000E19", etc. > [.]0+[eE][0-9]+ # ".0e0", ".000e500", etc. > ) > \s* > \z > }x; > > [0]: http://www.google.com/search?q=+site:perldoc.perl.org+%220+but+true%22 > [1]: http://perldoc.perl.org/perlsyn.html#Truth-and-Falsehood "0 but true" is the only special case in the number conversion code. The others are all valid floating point representations. If you're up for it, I don't think that it's documented anywhere that the false value returned by a logical operator is a special case: $ perl -wle '$a = 0 == 1; print ">$a<"; print $a + 0' >< 0 it is both the empty string, and a numeric zero. (That's not a special case in any conversion code. It's a dual value) Also, $! is a dual value, with the string value being the error string, and numeric value being the error code. On this system, the error string for 0 *is* an empty string, hence this is false: $ perl -wle '$! = 0; print ">$!<"; print $! + 0' >< 0 And if you're really up for it, there's a bug with no obvious fix if your system supports negative zero: $ perl -wle '$a = 0/-1; print $a ? "T" : "F"; print $a; print $a ? "T" : "F";' F -0 T the problem being that the implementation of true/false is is there a string value? Y: is it "0" or ""? is there a numeric value? Y: is it == 0 ... IEEE floating point has -0 numerically equal to 0, so that makes it false. But if you then cause that value to be used as a string (such as that print) then the string representation is cached, and it doesn't meet the value of falsehood. This *is* inconsistent with the documentation, and with the general intended behaviour, but I can't see a way to fix it. Whereas the behaviour of strings such as "0e0" and "00" and "0.0" is consistent with both the intent and the documentation. Nicholas ClarkThread Previous | Thread Next