2010-08-03 24 views
19

從Perl 5.10開始,現在可以從詞彙上限定上下文變量$_,顯式爲my $_;given/when構造。

有沒有人找到詞法的好用法$_?它是否使任何構造更簡單/更安全/更快?

情況會如何變得更復雜?詞彙$_是否在您的代碼中引入了任何錯誤? (因爲寫入$_的控制結構將使用詞法版本(如果它在範圍內),如果它包含任何子例程調用(由於動態範圍的丟失),這可以更改代碼的行爲)

最後,我想建立一個清單,闡明何時使用$_作爲詞彙,作爲全球性,還是根本不重要。


NB:作爲perl5-5.24這些實驗性功能是no longer part of perl

+0

我想回答你的問題主要是覆蓋[這裏](http://stackoverflow.com/questions/3393038/does-my-do-anything-if-is-implied)在回答我的問題。 – xenoterracide 2010-08-03 19:37:34

+0

@xenoterracide =>答案肯定涵蓋了詞彙'$ _'的一些方面,但不是全部。這就是我想在這裏介紹的內容。 – 2010-08-03 20:36:45

+0

我知道,但不妨有個好地方開始;) – xenoterracide 2010-08-03 21:02:31

回答

8

國際海事組織,一個偉大的事情出來的詞彙$_是新的_原型符號。

這使您可以指定一個子程序,以便它將採用一個標量,或者如果沒有提供它將會抓取$_

因此,而不是寫:

sub foo { 
    my $arg = @_ ? shift : $_; 

    # Do stuff with $_ 
} 

我可以這樣寫:

sub foo(_) { 
    my $arg = shift; 

    # Do stuff with $_ or first arg. 
} 

沒有大的變化,但是當我想要的行爲,它只是簡單得多。去除鍋蓋是一件好事。

當然,這會改變幾個builtins的原型(例如chr),這可能會破壞一些代碼。

總的來說,我歡迎詞彙$_。它爲我提供了一個工具,可以用來限制意外數據消除和功能之間奇怪的交互。如果我決定在函數體中使用$_,通過詞法化它,我可以確定我調用的任何代碼,$_都不會在調用代碼中被修改。

動態範圍很有趣,但大多數情況下我想要詞法範圍。再加上$_附近的併發症。我聽說過簡單地做local $_;的不合適性的可怕警告 - 最好是用for ($foo) { }代替。詞彙化的$_給我什麼,當我以任何方式本地化$_時,我想要100次99次。詞彙$_使得極大的方便性和可讀性更強大。

我的大部分工作都必須使用perl 5.8,所以我沒有在大型項目中使用詞彙$_的樂趣。不過,感覺這樣做可以讓$_更安全,這是一件好事。

+2

對於($ foo){...}而不是'local * _ = \ $ foo;''給出了什麼原因?根據我的經驗,後者要快一點(因爲它不必爲單個元素列表設置範圍和迭代器),但是如果有任何安全問題需要記住,我會感興趣。 – 2010-08-04 17:45:10

+1

埃裏克,我今天去找具體的參考資料,找不到它。我現在只記得在2009年年中某個時候發出警告,反對來自「我尊重我的意見的人」的「本地美元」。因此,除非我能更好地證實這一說法,否則最好不要只是傳聞而已。聲稱是本地化並沒有涵蓋所有具有公認特殊'$ _'的邊緣案例。我從來沒有發現錯誤報告或測試用例來備份警告。 – daotoad 2010-08-05 03:24:51

0

這裏沒有任何問題,雖然我傾向於在涉及到Perls的魔法時遵循某種「不問,不說」策略。即例程不是通常預計將依靠他們的同伴擰非詞彙數據作爲副作用,也不讓他們。

我已經測試了針對各種5.8和5.10版本的perl的代碼,而使用5.6描述駱駝偶爾參考。沒有任何問題。我的大部分東西最初是爲perl 5.8.8完成的。

3

我曾經在Inline模塊中玩過時發現一個issue(錯誤會太強烈)。這個簡單的腳本:

use strict qw(vars subs); 
for ('function') { 
    $_->(); 
} 
sub function { 
    require Inline; 
    Inline->bind(C => <<'__CODE__'); 
void foo() 
{ 
} 
__CODE__ 
} 

失敗,出現Modification of a read-only value attempted at /usr/lib/perl5/site_perl/5.10/Inline/C.pm line 380.錯誤消息。 Inline模塊的內部深處是一個子程序,它想修改$_,導致上面的錯誤信息。

使用

for my $_ ('function') { ... 

或以其他方式聲明my $_是一個可行的解決方法,這一問題。

Inline模塊已修補以解決此特定問題)。

1

[理由:一個簡短的附加答案,可能會經過的perl新手的快速總結。當搜索「perl詞彙主題」時,可以在這裏結束。]

現在(2015)我認爲這是常識,詞彙主題(my $_和一些相關功能)的引入導致一些難以檢測一開始意想不到的行爲就是marked作爲experimental,然後進入deprecation stage。的#RT119315


部分總結: 一個建議是這樣的事情use feature 'lextopic';to make use of a new lexical topic variable: $^_。 另一點是,當與明確的詞彙功能(,例如詞彙maplmap)組合時,「implicit name for the topicalizing operator ... other than $_」將最好地工作。這些方法是否能以某種方式挽救given/when尚不清楚。在實驗和貶值階段的來世,也許最終可能會生活在CPAN的河流中。