2017-05-26 147 views
1

的價值,我相當困惑的一個比較表達式的Perl中值:比較表達式在Perl

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

我得到如下結果:

why... 

那麼,爲什麼「1> 2」的結果爲空?這本書告訴我「$ a> $ b」是0或1。

+4

*這本書告訴我...... * - 哪本書? –

+1

這是真的,但它不是。 0是錯誤的,1是真的。但是2也是如此。 – Sobrique

+2

看起來你的書是錯的。瞭解您正在閱讀哪本書是很有用的,這樣我們可以阻止人們在將來閱讀它。 –

回答

4

好,抓住自己一杯咖啡,因爲它的時間走下來的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 <$ kIntervals時,我得到一個奇怪的結果(對我來說)。也許最後的原因是換擋操作員。我還有很多東西需要學習...... – xf1020

2

我鼓掌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; 
}; 

但我不知道你在做什麼這樣做可能是錯誤的