比较表达式在Perl

问题描述:

的价值,我相当困惑的一个比较表达式的Perl中值:比较表达式在Perl

print "why... ",1>2, "\n"; 

我得到如下结果:

why... 

那么,为什么“1> 2”的结果为空?这本书告诉我“$ a> $ b”是0或1。

+4

*这本书告诉我...... * - 哪本书? –

+1

这是真的,但它不是。 0是错误的,1是真的。但是2也是如此。 – Sobrique

+2

看起来你的书是错的。了解您正在阅读哪本书是很有用的,这样我们可以阻止人们在将来阅读它。 –

好,抓住自己一杯咖啡,因为它的时间走下来的perl的兔子洞,然后dualvars.

这是发生在这里的事情是 - perl做一些魔术“布尔”值进行比较。

正如你可能知道 - 在Perl“假”是(几乎)任何求值为零或空字符串。

所以0是假的,但这样是''(和一堆其他的东西)。

Perl通常从上下文中推断出来,而魔法“正常工作”。

print "yes" if 1>2; #just works. 

但是...怎么样打印布尔结果?那么,事实证明,因为它可能是要么“空字符串”或“0”的perl创建dualvar。

这是专门有两个的事情。

#!/usr/bin/env perl 
use strict; 
use warnings; 

use Scalar::Util qw (isdual dualvar); 

my $result = 1>2; 

if (isdual ($result)) { 
    print "\$result is a dualvar\n"; 
} 

print "Number:", 0+$result,"\n"; 
print "String:",''.$result,"\n"; 

如果你试图在正常值这些操作:

my $number = ''; 
print 0+$number; 

你会得到

Argument "" isn't numeric in addition (+) 

可以复制这个魔法,使用dualvar

my $thing = dualvar (666, "the beast"); 

print 0+$thing,"\n"; 
print $thing,"\n"; 

虽然大多数情况下你不需要 - 如果你干涉太多,这可能会做很奇怪的事情。但通常“结果”是双目标,如[email protected]$!

open (my $fh, '<', "not_here"); #generates $! 
print "\$! is dual\n" if isdual ($!); 
print 0+$!,"\n"; 
print $!,"\n 

此打印:

$! is dual 
2 
No such file or directory 

在你的问题的情况下 - 这是因为无论是空字符串或零是“假”和Perl不知道什么样的“假”,你会的需要。因此,它提供给你。

因为你正在做一个print Perl的决定,您使用字符串现在,并使用双变种的字符串部分 - 空字符串。

你可以做,而不是:

print "why... ",0+(1>2), "\n"; 

添加零强制切换到“数字”,并为您提供:

why... 0 

但长期和短期的它真的是 - 不要做你在做什么,这是不好的风格。如果某件事情是虚假的,那么你需要一个特定的价值 - 然后说出这个价值是什么。有没有错:

return 0 if 1>2; 

或者:

print "Why: ", 1>2 ? "1" : "0", "\n"; 
+0

谢谢。我扔掉了我的书。顺便说一句,我有上面的问题,因为这个表达式:$ index =(($ index - $ kIntervals)>>($ index> $ kIntervals))+ $ kIntervals;当$ index xf1020

我鼓掌Sobrique's explanation of dualvars但我不认为这是必要的Perl这样深奥的部分涉及到解决您的问题

Perl的dualvars是更为常见比你可以想像的,并且主要用于避免重复的字符串和整数之间的转换

my $v1 = "10"; 
my $v2 = $v1 + 20; 

在此示例中,变量$v1被设置为字符串"10"。该字符串必须被转换为整数,以进行接下来的操作,这是添加的号码20并将结果存储在$v2。为了避免重复转换如果$v1数字版本碰巧再次需要,就变成了dualvar其保持二者的串和数值和计算结果为"10"10根据如何使用它

所有的这些都是在Perl

  • 的数值为零

  • "0"

    (注意比评价为数值零的任何其它字符串,如"0.0""0E99",是

  • 空字符串""

  • undef

  • 空列表()

还有什么是真的,所以子程序和表达可能对一个布尔值,只要它遵守这些规则返回相当多的东西。在实践中,Perl的内置运营商通常是这恰好是返回一个固定值dualvar等于零的数量和空字符串作为字符串

我,因为上面的问题这种表达的:

$index = (($index - $kIntervals) >> ($index > $kIntervals)) + $kIntervals 

$index < $kIntervals,我得到一个奇怪的结果(对我来说)。也许最终的原因是移位运算符

这里,值$index > $kIntervals用作数字,因此它的值将为0或1,如您所期望的。我不知道从这个表达式得到的结果是什么,但<<将执行逻辑转换并将第一个操作数视为简单位模式。如果你想要做一个算术移位,它基本上是二的幂乘法,那么您需要临时启用use integer,这样

$index = do { 
    use integer; 
    (($index - $kIntervals) >> ($index > $kIntervals)) + $kIntervals; 
}; 

但我不知道你在做什么这样做可能是错误的