문제

$a="";
$b="n";
$c = !$a;
$d = !$b;
print $c , "\n" , $d;
if($d == 0){
    print "zero";
}

I wrote this perl program i expected the output to be as follows

1  
0Zero

but it prints

1  
zero

can any one explain me why is it like that??

도움이 되었습니까?

해결책

Variables in Perl are treated as either numbers or strings depending on the context. If you haven't treated something as a number when assigning to it, Perl will treat it like a string when you print it.

Because of this, false values are a bit different in Perl than in languages with stronger typing (emphasis added by me):

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. Most Perl operators that return true or false behave this way.

So, the issue here is that ! is a logical operator rather than an arithmetic one. Therefore, it returns a logically false value, which is represented in different ways depending on the context.

If you want to make sure something is treated as a number, you have a few options. You can perform an arithmetic operation, which will make Perl consider the result a number:

$d=!$b+0;
print $d;

You can use sprintf or printf to explicitly control the display:

printf '%d', $d;

Or you can use int:

print int $d;

(Note: this all may seem a bit complicated. But it was designed so that the language will just do what you want, and you won't have to think about it. And normally it does. There are only occasional edge cases where you need to do something other than Perl's default behavior.)

다른 팁

In perlsyn, under Truth and Falsehood you read

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. Most Perl operators that return true or false behave this way.

This is what you experience. $a is false value, so !$a, assigned to $c, becomes a true value, accordingly printed as 1. $b is a true value, so !$b, assigned to $d, becomes that special false value. In the print statement (print $c , "\n" , $d;), it is evaluated in string context, so the empty string is printed. The if statement ($d == 0) evaluates it in number context, so it is a 0, hence zero is printed.

!$b evaluates to empty string '', as false values are not represented by zero when stringified by print(), "$bool", or some other string operation.

$a="";
$b="n";
$c = !$a;
$d = !$b;
print $c , "\n" , $d;
if($d == 0){
    print "zero";
}

use Data::Dumper;
print Dumper {
  '$a' => $a,
  '$b' => $b,
  '$c' => $c,
  '$d' => $d,
  '$d == 0' => $d == 0,
};

output

$VAR1 = {
      '$d == 0' => 1,  # boolean true
      '$b' => 'n',
      '$d' => '',      # boolean false
      '$c' => 1,
      '$a' => ''
    };

Perl operators such as ! that return boolean values return a special value for false: it is "" when used in string context and 0 when used in numeric context.

So when you print it, it is "", not "0". But if you try to use it as a number, it doesn't give a warning the way "" does. Compare:

perl -wle'$false = !1; print "string: ", $false, " number: ", 0+$false'
string:  number: 0

and

perl -wle'$empty = ""; print "string: ", $empty, " number: ", 0+$empty'
Argument "" isn't numeric in addition (+) at -e line 1.
string:  number: 0
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top