Skip to Content

perl 在函數中宣告 my $_

以前在學 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;       # 使用 local
    s/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;          # 使用 my
    s/123/abc/;             # 【重點】預設取代的對像是 $::_ , 也就是 $main::_
    print "in  : $_\n";     # $_ = 123 , 區域變數完全沒有被取代
    print "out : $::_\n";   # $::_ = abc , 所以 $::_ 反而被取代了
}
 
結果如下:
in  : abc
out : abc
123
 
in  : abc
out : 123
123
 
in  : 123
out : abc
abc
 
總之,重點就是這二行要特別小心
my $_ = shift;
s/123/abc;
在副程式中宣告 my $_ 之後,就不能用 s/123/abc/; 這種方式來處理,因為它預設是處理全域變數的 $_,而不是副程式中宣告的 $_,若不注意,就會有非預期的結果。
 
如果要處理,就不可以偷懶,要寫清楚變數名稱
 
my $_ = shift;
$_ =~ s/123/abc;
這樣才是針對內部宣告的 $_ 來進行取代處理。
 

回應

發表新回應

這個欄位的內容會保密,不會公開顯示。
  • 自動將網址與電子郵件地址轉變為連結。
  • 自動斷行和分段。
  • 可使用的 HTML 標籤:<a> <address> <b> <blockquote> <br> <caption> <center> <cite> <code> <dd> <del> <div> <dl> <dt> <em> <h1> <h2> <h3> <h4> <h5> <h6> <hr> <i> <img> <ins> <li> <ol> <p> <pre> <span> <strike> <strong> <sub> <sup> <table> <tbody> <td> <th> <tr> <u> <ul>
    Allowed Style properties: background, background-attachment, background-color, background-image, background-position, background-repeat, border, border-bottom, border-bottom-color, border-bottom-style, border-bottom-width, border-collapse, border-color, border-left, border-left-color, border-left-style, border-left-width, border-right, border-right-color, border-right-style, border-right-width, border-spacing, border-style, border-top, border-top-color, border-top-style, border-top-width, border-width, bottom, caption-side, clip, color, direction, empty-cells, font, font-family, font-size, font-size-adjust, font-stretch, font-style, font-variant, font-weight, height, left, letter-spacing, line-height, list-style, list-style-image, list-style-position, list-style-type, margin, margin-bottom, margin-left, margin-right, margin-top, max-height, max-width, min-height, min-width, overflow, padding, padding-bottom, padding-left, padding-right, padding-top, right, table-layout, text-align, text-decoration, text-indent, text-transform, top, unicode-bidi, vertical-align, white-space, width, word-spacing, z-index

更多關於格式選項的資訊

CAPTCHA
驗證碼只有阿拉伯數字, 這是躲廣告用的, 麻煩你輸入了.
Image CAPTCHA
Enter the characters shown in the image.


story | about seo