2014-07-24 45 views
1

如果我有一個已經被定義爲一個字符串變量,我應該保護賦給子程序的字符串嗎?

my $x = "abc"; 
sub p { ... } 

我接下來要p("$x")或可以做p($x)p($hash->{x})

所有作品在我的測試。任何缺點不引用?

+0

做什麼樣的結果當你嘗試上面提到的選項時,你會得到什麼? – fugu

+0

所有作品在我的測試中。 –

+0

第三種情況應該不起作用,因爲您沒有在示例中定義'$ hash',但是不需要「保護」傳遞給子例程的字符串。 –

回答

8

不管它是否被用作子程序調用參數,它通常被認爲是不好的做法,引用一個標量變量,如"$s",原因有二

  • 你是不必要的製作重複值的

  • 您可以調用一個重載字符串化行爲

當然,第二個也可能是一個很好的理由選擇做到這一點,因爲你希望使用stringify特殊行爲。

使用裸變量作爲子例程參數的唯一缺點是,由於Perl通過引用傳遞值,因此可以從子例程內修改該值。但是,您需要修改@_的元素,這是非常難以做到的。

子程序的一般形式是這樣的

sub proc { 
    my ($p1, $p2, $p3) = @_; 
    # Do stuff with $p1, $p1, $p3 
} 

中,你與參數的安全副本反正工作和修改的情況下他們不會對實際參數沒有影響

8

p($x)p($hash->{x})都沒問題。你已經把這些變量的副本,當你做

my ($x) = @_; 

my $x = shift; 

無需創建呼叫者的身邊副本(使用"$x")了。


如果你沒有複製的元素,你可以,如果你在子改變一個全局變量有一個問題,你也傳遞全局變量作爲參數傳遞給子。

$ perl -E' 
    my $x; 
    sub f { $x = "def"; say $_[0] } 
    $x = "abc"; 
    say $x; 
    f($x); 
' 
abc 
def 

但是,你爲什麼要那樣做?這樣做的合理的情況是我能想到的是以下內容:

$ perl -E' 
    sub f { "def" =~ /(.*)/s; say $_[0] } 
    "abc" =~ /(.*)/s; 
    say $1; 
    f($1); 
' 
abc 
def 

所以也許f("$1")有道理的時候,但是僅此而已。