Reputation: 1112
I am trying to execute this code. What puzzles me is why doesn't this comparison return any value when false. Is this the default behavior of these comparison operators?
my $output = (2 <= 1);
print "value=$output";
Will a comparison operator return undef
when its logical check fails?
Upvotes: 4
Views: 1374
Reputation: 132802
return 1 for true and a special version of the defined empty string, "" , which counts as a zero but is exempt from warnings about improper numeric conversions, just as "0 but true" is.
The value you get back is actually a dualvar. It has separate numeric and string values (not a special version of the empty string, really). The numeric value is 0 and the string value is the empty string. You used the string portion, which is empty, but the 0 is still there. You can look inside the variable records with Devel::Peek:
use Devel::Peek;
my $result = ( 1 == 2 );
Dump( $result );
In the SV (scalar value) thing behind the scenes, you see the string value in the PV and the numeric value in the IV And NV (the integer and numeric values):
SV = PVNV(0x7fe602802750) at 0x7fe603002e70
REFCNT = 1
FLAGS = (PADMY,IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x7fe6026016b0 ""\0
CUR = 0
LEN = 16
There are other sorts of dualvars too. The $!
error variable has the error number and the error text, for instance (and I talk about that in Mastering Perl). This isn't something you normally have to worry about because Perl does the right thing for the context.
If you always want a numeric value, use it in a numeric context:
my $numeric = 0 + $result; # 0
You can create your own dualvars with Scalar::Util's dualvar
, and you can check if a scalar is a dualvar with isdual
.
use Scalar::Util qw(isdual);
my $result = ( 1 == 2 );
print isdual($result) ? "dualvar" : "Not dualvar";
If you wanted to check that the value you got back was defined (you said it wasn't), you can check with defined. An empty string is defined, though. If you want to check that it's not the empty string, you can use length. These help when the value you have isn't printable.
Upvotes: 13
Reputation: 444
Comparisons can return a special false value that is an empty string or 0 depending on the context in which it is evaluated. If you are looking for specific values for true and false it is much safer to use a statement like this:
my $output = ( 2 <= 1 ) ? 1 : 0;
The following code will illustrate the behaviour of the special false value.
use 5.014;
say ( 2 <= 1); # prints nothing
my $output = ( 2 <= 1 ) ? 1 : 0;
say $output; # prints 0
$output = ( 2 > 1 ) ? 1 : 0 ;
say int $output; # prints 1
say $output; # prints 1
$output = ( 2 <= 1 ) ;
say int $output ; # prints 0
If you're unfamiliar with the ? : construct see: http://perldoc.perl.org/perlop.html#Conditional-Operator
Upvotes: 1
Reputation: 13792
That expression returns an empty string (""
), which Perl considers as a false value in evaluating sentences like if
or unless
.
In Perl, 0
, "0"
and an empty string (""
) are false. undef
is also false, but you may get a warning. Anything else is true.
Upvotes: -1
Reputation: 4013
Boolean operators return 1 on true and '' on false. You are trying to print the empty string.
Try this for a test
use strict;
use warnings;
my $output = (2 <= 1);
print $output ? "value=|$output|" : "value=<$output>";
Upvotes: 3