2012-07-09 46 views
1

我有一種情況,我期望將變量作爲字符串或數字傳遞給我。將Perl字符串評估爲零僅適用於數字

sub foo { 
    # These can be either strings or numbers 
    my ($bar, $var, $star) = @_; 

    # I need to check to see if $bar is the number 0 (zero) 
    if ($bar == 0) { 
     # Do super magic with it 
    } 
} 

不幸的Perl試圖做$bar超級魔法時,它包含一個字符串。

我如何告訴Perl在$bar上做超級魔法當且僅當它是號碼 0(零)?

我知道Perl基於上下文的基本解釋,這是這裏的基本問題。這個問題的一個可能的解決方案是使用正則表達式,這很好,但我想知道是否有另一個更「直接」的解決方案。

在此先感謝。

+1

1)你能舉出與超級魔法相匹配的事物嗎? 2)你可以使用字符串相等運算符'eq'嗎?這將捕獲$ bar等於'0'的位置,並且將忽略,但不包括'0.0'或'00'等其他形式。 – 2012-07-09 15:06:20

回答

4

我會親自去什麼@ Disco3的評論說。

if ($bar eq 0) { ... } 

這適用於$bar = 0$bar = 'foo'$bar = 123給出預期的結果。

這裏有一個有趣的事實,但:

use Benchmark qw(cmpthese); 
my $bar = '0'; 

cmpthese(-1, { 
    'quoted' => sub { $bar eq '0' }, 
    'unquoted' => sub { $bar eq 0  }, 
    'regex'  => sub { $bar =~ m/^0$/ }, 
}); 

標杆這三種解決方案告訴我們,不帶引號的0是做到這一點的最快方式。

   Rate regex quoted unquoted 
regex  4504851/s  --  -70%  -76% 
quoted 15199885/s  237%  --  -19% 
unquoted 18828298/s  318%  24%  -- 
+2

但最慢的時間不到四分之一微秒,誰在乎?應該首先選擇最清晰的解決方案。 – Borodin 2012-07-09 15:33:33

+0

我同意,這就是爲什麼我說這是一個有趣的事實。;)我認爲'eq'比正則表達式更清晰,但這是我個人的看法。我相信每個人都必須自己決定,或者按照編碼準則告訴他們。 – simbabque 2012-07-09 15:37:40

+0

它不起作用的是'0.0',我認爲這個代碼的意思就是拋出一個。 – darch 2012-07-09 18:20:26

2

爲什麼不:

if ($bar =~ m/^0$/) { 
+1

我知道這會工作,但我想知道是否有一個解決方案,不涉及正則表達式。 – Rico 2012-07-09 15:16:41

+1

國際海事組織,在這種情況下,正則表達式使目標明確。 – JRFerguson 2012-07-09 15:57:18

2

這取決於你的意思是「數字0」。顯然,你包含一個字符串0爲零。但是你說三個字符串0.0

如果你只是想匹配一個字符串0,使用

if ($bar eq '0') { 
    ... 
} 

如果你想配什麼的Perl認爲數字零,使用

use Scalar::Util qw(looks_like_number); 

if (looks_like_number($bar) && $bar == 0) { 
    ... 
} 
0

之間looks_like_number和數值的比較,你可以很容易地得到相當好的結果:

use Scalar::Util qw(looks_like_number); 
use Test::More tests => 7; 

sub is_numerically_zero { 
    my ($string) = @_; 

    return (looks_like_number($string) and $string == 0); 
} 

for my $string (qw(0 0.0 0e0), ' 0 ') { 
    ok(is_numerically_zero($string)); 
} 

for my $string (qw(duckies 123), '') { 
    ok(not is_numerically_zero($string)); 
} 

這假定你不想只匹配字符串'0'