Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does Perl return when a numeric comparison is false?

Tags:

perl

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?

like image 502
chidori Avatar asked Dec 05 '22 05:12

chidori


2 Answers

The relational operators

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.

like image 126
brian d foy Avatar answered Dec 27 '22 06:12

brian d foy


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>";
like image 21
JGNI Avatar answered Dec 27 '22 06:12

JGNI