Nice golf, but your solution never returns 0, which is what the original snippet does. Furthermore, if $status is '0E0' or '0.0' it returns 1, because they both are true values, though numerically zero.
See:
for ( 0, 0.0, "0", "0.0", "0E0", 1, "1" ) {
print $_, "\t", !!$_, "\t", ( $_==0 ? 0 : 1 ), "\n";
}
prints out
0 0
0 0
0 0
0.0 1 0
0E0 1 0
1 1 1
1 1 1
Best regards
Antonio Bellezza
Update:
As pointed out in other posts, the same behaviour of "0.0" and "0E0" is true for strings not representing numbers, which have true values, but behave as 0 in numeric comparison. The difference is a warning of type
Argument "xyz" isn't numeric in numeric eq (==) at - line 3.
when -w is enabled.
| [reply] [d/l] |
True! Some things don't translate well from my former (C) world into Perl. I hadn't considered the possibility (or perversity) of setting a status value to a string representation of zero.
It wasn't aimed at the OP in anycase.
Well It's better than the Abottoire, but Yorkshire!
| [reply] [d/l] |
That's how I used to do it in C/C++ before it had a bool type, when it was necessary to canonize the value.
If that's too idiomatic, using return asbool($status) where that's an inlined function would be readable and just as efficient.
Note that it does a bit more than it does in a stronly-typed language. What if $status is not an int at all? The normal boolism is to treat undef and empty strings as false, also, and in one known case 0e1 is used as zero-but-true. The original test will be different from that; the !! idiom preserves it.
—John | [reply] [d/l] [select] |
| [reply] |
return $status && 1; # canonize false, leave true as-is
for completness sake.
update: I got that backwards. && returns the last part evaluated, and skips the right side if the left already determines the outcome. So, if $status is false it returns it unchanged; if true it evaluates the right hand side and gets a numeric 1. It canonizes true, leaves false as-is.
$status || 0; will return $status unchanged if true, and check the rhs if false. So that canonizes false and returns true unchanged. | [reply] [d/l] [select] |
return $status && 1; # canonize false, leave true as-is
That would be great except it doesn't canonize false. It returns $status if $status is false. So, for example, if $status is "" it will return "", not 0.
-sauoq
"My two cents aren't worth a dime.";
| [reply] [d/l] |
$status || 0;
I'll agree that snippet "canonizes false" but it still isn't what the original did. The original canonized numerical equality with 0. The above snippet will return "foo" because "foo" is true. The original would have returned 0 because "foo" == 0 is true.
OK, OK, OK. I'll just be getting on with my life now. :-)
-sauoq
"My two cents aren't worth a dime.";
| [reply] [d/l] [select] |
How about...
return 0+($status!=0)
Decent golf score and I think that works just like the original. Can anyone think of a counterexample?
-sauoq
"My two cents aren't worth a dime.";
| [reply] [d/l] |
Argument "fred" isn't numeric in numeric ne (!=) line 1
0
with -w, which admittedly the original did too.
The result of ($status!=0) will always be either 0 or 1 won't it?
In which case, the 0+ isn't doing anything? In fact neither then are the () nor the return?
I get the distinct feeling I'm walking into the trap here, but I cannot see it.
Well It's better than the Abottoire, but Yorkshire! | [reply] [d/l] [select] |
The result of ($status!=0) will always be either 0 or 1 won't it?
It will either be 1 or "" (the empty string.) All of the comparison operators work this way with the obvious exceptions of <=> and cmp. So do logical negation and most of the file test operators.
I get the distinct feeling I'm walking into the trap here, but I cannot see it.
Well, it wasn't really meant to be a trap but, yes, you walked into it. :-)
-sauoq
"My two cents aren't worth a dime.";
| [reply] [d/l] [select] |