2016-09-29 77 views
4

我使用的是一篇發表在Science文章中的工具,但它給我帶來了很多麻煩,因爲我對Perl並不熟悉。

的代碼包含:

return $equa if /\@BOUNDARY/; 

我相信,代碼應該返回$equa如果它包含文本@BOUNDARY,但它沒有做到這一點。提供的代碼是否有錯誤?

我想將其更改爲的:

if ($equa =~ /\@BOUNDARY/) { 
    return $equa; 
} 

這是否執行同樣的功能?


作爲參考,在原有代碼的整體功能是:

sub correctBoundaryReac { 
    my $equa = shift; 
    print $equa; 
    return $equa if /\@BOUNDARY/; 
    my($left, $arrow, $right) = ('', '', ''); 
    if($equa =~ /^(<--|<==>|-->) (.+)/){ 
     $arrow = $1; 
     $right = $2; 
     $left = $right; 
     $left =~ s/\@\S+/\@BOUNDARY/g; 
    } 
    elsif($equa =~ /(.+) (<--|<==>|-->)$/){ 
     $left = $1; 
     $arrow = $2; 
     $right = $left; 
     $right =~ s/\@\S+/\@BOUNDARY/g; 
    } 
    else{ 
     die "Don't know how to fix bounadry reaction: $equa\n"; 
    } 
    return "$left $arrow $right"; 
} 
+6

'返回$ EQUA如果/ \ @邊界/;'是一樣的'返回$ EQUA如果$ _ =〜/ \ @ BOUNDARY /;'有兩個變量:$ equa和$ _ – toolic

+1

'/ $ pattern /'將匹配應用於當前保存在默認變量'$ _'中的任何內容。所以你提供的是不同的。例如,for(@arr)'在'$ _'中有數組元素,因爲它迭代它們。這只是一個例子,'$ _'在Perl中使用很多。查看前面的代碼,看看'$ _'中可以包含什麼。 – zdim

+0

當您更改代碼時,代碼是否適用? – toolic

回答

4

如前所述,if (/$pattern/)表示if ($_ =~ /$pattern/)。請參閱General Variables in perlvar。那麼問題是–你在代碼中顯示的$_是什麼?

Perl中的許多內置運算符和運算符默認使用$_。但是子程序不會使用$_來做任何事情,據我所知。 @_獲得參數,但它是一個完全不同的變量。

然而,子裏面。如果這是爲了在你展示的代碼從子的封閉範圍$_可見

use feature 'say'; 

sub show_it { say "I see: $_" } 

for ('a'..'c') { 
    show_it(); # prints with a through c 
} 

,這意味着在變量$_子檢查模式'@BOUNDARY' –但是從調用子的範圍。這至少可以說是不好的做法,並且很容易導致微妙的錯誤。任何時候調用範圍中的代碼發生變化時,都必須查看子集,但我們並未通過子接口警告($_不是參數)。此外,這甚至不需要,因爲調用代碼可以檢查並調整通話。

我寧願相信你展示的是一個簡單的錯誤,在這種情況下,它應該是

return $equa if $equa =~ /\@BOUNDARY/; 

這意味着子首先檢查輸入是否有這個已經,如果它只是回報它。其餘顯示的代碼支持這一點 - 這都是關於'@BOUNDARY'

1

這是一個Perl主義是爲那些誰沒有開始進入神祕的藝術非常直觀。

Perl有一個所謂的「隱藏變量」,$_。實質上,任何帶有單個參數或比較的函數調用實際上都會取代$_替代缺失值。例如,

foo() if /bar/; 

實際上相當於

if ($_ =~ /bar/) { 
    foo(); 
} 

這使得,如果你認爲一個比較操作符是一個函數調用的直覺,以及第一例子具有我前面提到的缺少的參數。

就你的情況而言,如果$_變量的值與正在討論的正則表達式的值相匹配,代碼正在做的是返回某個變量的值。

+1

***隱藏變量***是錯誤的。 '$ _'等稱爲***特殊變量***或***預定義變量***。 – Borodin

+0

它被稱爲「默認變量」。 「隱藏變量」是一個很好的名字,我會開始使用它。 – Schwern

1
return $equa if /\@BOUNDARY/; 

是短期的

return $equa if $_ =~ /\@BOUNDARY/; 

所以從if語句修改器if語句結果轉換在

if (/\@BOUNDARY/) { 
    return $equa; 
} 

if ($_ =~ /\@BOUNDARY/) { 
    return $equa; 
} 

但是,您的當前代碼完全可能是錯誤的。它apears是

return $equa if $equa =~ /\@BOUNDARY/; 

應該被使用,在這種情況下,這是完全正常使用

if ($equa =~ /\@BOUNDARY/) { 
    return $equa; 
} 
相關問題