2010-06-10 12 views
6

Perl read ($ buf) işlevinin $ buf değişkeninin içeriğini nasıl değiştirebileceğini anlayamıyorum. $ buf bir referans değildir, bu yüzden parametre kopya ile verilir (c/C++ bilgimden). Peki, $ buf değişkeni arayanda nasıl değiştirilir?Perl read() işlevinin arkasındaki sihir ve bir ref değil arabellek nedir?

Bu bir bağ değişkeni midir? setbuf hakkında C dokümantasyon da benim

# 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 

cevap

11

Büyü gerekmiyor - eğer yapacaksanız, tüm perl alt yordamları ad-soyadtır. perlsub Quoth:

dizi @_ yerel dizidir, ama onun elemanları gerçek sayıl parametreleri için diğer adları vardır. Özellikle, bir $ _ [0] öğesi güncellendiyse, karşılık gelen argüman güncellenir (veya güncellenemezse bir hata olur). Örneğin

: En "Örnek 2" de

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

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

, sizin read_it alt kopya tarafından daha sonra "yerinde" değiştirilmiş kopya sözcük $buf için @_ ilk unsur, read() numaralı telefonu arayın. yerine kopyalama $_[0] aktarın ve ne olduğunu görün:

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

İlgili dokümana gösterdiğiniz işaret için çok teşekkürler ve hileler işe yarıyor, teşekkürler –

0

read() oldukça zor ve belirsiz yerleşik bir fonksiyonudur ve bu yüzden büyü yapabilir. Bir function prototype bildirerek olsa da, kendi fonksiyonları ile benzer bir şey başarabilirsiniz:

sub myread(\$) { ... } 

argüman beyanı \$ savı kesinlikle bir referans olarak kabul anlamına gelir.

Yerleşik read'daki tek sihir, dolaylı olarak veya düzenli işlevler için çalışmayan bir dosya yöntemi olarak adlandırıldığında bile çalışabilmesidir.

+3

Bir alt yordam geçirilen değişkeni değiştirmek için bir prototip veya açık geçmesini referans-ile-gerekmez: 'alt foo {$ _ [ 0] ++} '. – FMc

+0

+1 Bu OP'nin sorusu için tam olarak bir noktaya değin değil, prototipler ve * bona fide * perl referansları (sembolik referanslar değil) bu alanda bilmeniz önemlidir. – pilcrow

+0

@FM, iyi yakalama. Her zaman unuyorum ki '@' bu şekilde kullanılabilir. –