heavenchou - 二, 2017/01/03 - 22:06
以前在學 Perl 時,知道在函數中宣告變數可以用 local 或 my ,local 表示在它的宣告的區塊中,可以在該區塊調用的子函數中繼續使用。而 my 宣告的變數就不行了。
不過當時有一個特殊的限制,就是針對這個特殊的變數 $_,只能宣告為 local。不過在後來的新版本中,有看到可以宣告為 my,對此我也沒特別注意,今天寫程式時,就試用了一下,結果程式有不在預期中的結果,還 debug 半天,才發現就是 my $_ 造成的。剛剛寫了個小程式測試,才大概看出它的特性。
程式:
$_ = "123";test1($_);print "$_\n\n"; # $_ = 123$_ = "123";test2($_);print "$_\n\n"; # $_ = 123$_ = "123";test3($_);print "$_\n\n"; # $_ = abc , 在函數中被取代了sub test1{local $_ = shift; # 使用 locals/123/abc/; # 預設是處理 $_print "in : $_\n"; # $_ = abc , 被取代了print "out : $::_\n"; # $::_ = abc , $::_ 暫時被取代了}sub test2{my $_ = shift; # 使用 my$_ =~ s/123/abc/; # 取代的對像是內部的 $_print "in : $_\n"; # $_ = abc , 被取代了print "out : $::_\n"; # $::_ = 123 , $::_ 完全沒有參與}sub test3{my $_ = shift; # 使用 mys/123/abc/; # 【重點】預設取代的對像是 $::_ , 也就是 $main::_print "in : $_\n"; # $_ = 123 , 區域變數完全沒有被取代print "out : $::_\n"; # $::_ = abc , 所以 $::_ 反而被取代了}
結果如下:
in : abcout : abc123in : abcout : 123123in : 123out : abcabc
總之,重點就是這二行要特別小心
my $_ = shift;s/123/abc;
在副程式中宣告 my $_ 之後,就不能用 s/123/abc/; 這種方式來處理,因為它預設是處理全域變數的 $_,而不是副程式中宣告的 $_,若不注意,就會有非預期的結果。
如果要處理,就不可以偷懶,要寫清楚變數名稱
my $_ = shift;$_ =~ s/123/abc;
這樣才是針對內部宣告的 $_ 來進行取代處理。
重要度:
文章分類:
電腦標籤:
- 瀏覽次數:15047
發表新回應