2010-06-10 3 views
6

Perl read ($ buf) 함수가 $ buf 변수의 내용을 어떻게 수정할 수 있는지 이해할 수 없습니다. $ buf는 참조가 아니므로 매개 변수는 copy (내 c/C++ 지식에서)에 의해 제공됩니다. 그러면 $ buf 변수가 호출자에서 어떻게 수정 될까요?ref()가 아닌 perl read() 함수와 버퍼 뒤에있는 마법은 무엇입니까?

동점 변수입니까? 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

마술은 필요하지 않습니다. 모든 펄 서브 루틴은 원한다면 별 별 호출입니다. perlsub Quoth :

배열 @_ 로컬 배열이지만, 그 요소는 실제 스칼라 파라미터에 대한 별명 이다. 특히 요소 $ _ [0] 이 업데이트되면 해당 인수가 업데이트됩니다 (업데이트 할 수없는 경우 오류가 발생 함). 예를 들어

: 당신의 "실시 예 2"의

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

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

하여 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

관련 문서에 대한 포인터를 보내 주셔서 감사 드리며 트릭을 작동합니다. –

0

read() 아주 애매하고 불분명 내장 함수이기 때문에 마술을 할 수 있습니다. 당신은 function prototype을 선언하지만, 자신의 기능과 비슷한을 수행 할 수 있습니다

sub myread(\$) { ... } 

인수 선언 \$는 인수가 암시 적으로 참조로 전달되는 것을 의미한다.

내장 된 read의 유일한 마술은 간접적으로 또는 파일 핸들 방식으로 호출되는 경우에도 정상적으로 작동하지 않는다는 것입니다.

+3

당신은 서브 루틴에 전달 변수 수정하기 위해 프로토 타입 또는 명시 적 통과별로 참조가 필요하지 않습니다'서브 foo는 {$를 _ [ 0] ++}'. – FMc

+0

+1 이것은 OP의 질문에 대해서는별로 중요하지 않지만,이 도메인에서 알아야 할 프로토 타입과 * 정당한 참조 (symbolic refs가 아닌)는 중요합니다. – pilcrow

+0

@FM, 잘 잡습니다. 나는'@ _ '이 그런 식으로 사용될 수 있다는 것을 항상 잊는다. –