2010-06-10 41 views
6

我不明白Perl讀取($ buf)函數是如何修改$ buf變量的內容的。 $ buf不是一個引用,所以參數是由copy(來自我的c/C++知識)給出的。那麼在調用者中如何修改$ buf變量?perl read()函數和不是ref的緩衝區背後有什麼魔力?

這是一個領帶變量或什麼?約setbuf以C文檔中也相當難以捉摸和我不清楚

# Example 1 
$buf=''; # It is a scalar, not a ref 
$bytes = $fh->read($buf); 
print $buf; # $buf was modified, what is the magic ? 

# Example 2 
sub read_it { 
    my $buf = shift; 
    return $fh->read($buf); 
} 
my $buf; 
$bytes = read_it($buf); 
print $buf; # As expected, this scope $buf was not modified 

回答

11

不需要任何魔法 - 如果您願意,所有perl子例程都是按別名調用的。答曰perlsub

陣列@_是本地陣列,但它的元件是用於實際的標量參數別名 。特別是,如果更新元素$ _ [0] ,則會更新相應的參數(或者如果它不是可更新的,則會發生錯誤 )。

例如:

sub increment { 
    $_[0] += 1; 
} 

my $i = 0; 
increment($i); # now $i == 1 

在你的「實施例2」中,您的read_it拷貝@_詞法$buf第一元件,其複製然後被「就地」改性由致電read()。通過在$_[0],而不是複製,並看看會發生什麼:

sub read_this { 
    $fh->read($_[0]); # will modify caller's variable 
} 
sub read_that { 
    $fh->read(shift); # so will this... 
} 
+0

非常感謝指向相關文檔的指針,並且您的技巧很有用,非常感謝 – 2010-06-10 06:37:15

0

read()是一個內置的功能,所以可以做魔術。你可以做到用自己的功能類似的事情,不過,通過聲明function prototype

sub myread(\$) { ... } 

的參數聲明\$意味着該參數作爲參考隱式傳遞。

內置read中唯一的魔法就是它在間接調用或作爲文件句柄方法工作時不起作用,它不適用於常規函數。

+3

你不需要樣機或明確的傳遞,通過引用以修改傳遞到子程序的變量:'子富{$ _ [ 0] ++}'。 – FMc 2010-06-10 05:24:49

+0

+1這不太適合OP的問題,但原型和*真實* perl引用(不是符號引用)在這個領域中很重要。 – pilcrow 2010-06-10 13:56:53

+0

@FM,很好。我總是忘記了'@ _'可以這樣使用。 – 2010-06-10 14:05:16