2014-01-12 2 views
4

, 폐쇄을 이해하려고 노력 perl-faq 통해 읽고 perlrefcoderef 그 예를 찾을 수 있지만 :

sub add_function_generator { 
    return sub { shift() + shift() }; 
} 
my $add_sub = add_function_generator(); 
my $sum = $add_sub->(4,5); 

여기

sub newprint { 
    my $x = shift; 
    return sub { my $y = shift; print "$x, $y!\n"; }; 
} 
$h = newprint("Howdy"); 
&$h("world"); 

변수에 저장된 함수를 호출의 두 가지 형태가 있습니다.

&$func($arg) 
$func->($arg) 

이들이 완전히 동일합니까 (구문 만 다름) 또는 여기에 약간의 차이가 있습니까?

답변

13

차이는 없습니다. 증명 : 각 버전에 의해 생성 된 옵 코드 :

$ perl -MO=Concise -e'my $func; $func->()' 
8 <@> leave[1 ref] vKP/REFC ->(end) 
1  <0> enter ->2 
2  <;> nextstate(main 1 -e:1) v:{ ->3 
3  <0> padsv[$func:1,2] vM/LVINTRO ->4 
4  <;> nextstate(main 2 -e:1) v:{ ->5 
7  <1> entersub[t2] vKS/TARG ->8 
-  <1> ex-list K ->7 
5   <0> pushmark s ->6   
-   <1> ex-rv2cv K ->-   
6    <0> padsv[$func:1,2] s ->7 
$ perl -MO=Concise -e'my $func; &$func()' 
8 <@> leave[1 ref] vKP/REFC ->(end)  
1  <0> enter ->2      
2  <;> nextstate(main 1 -e:1) v:{ ->3 
3  <0> padsv[$func:1,2] vM/LVINTRO ->4 
4  <;> nextstate(main 2 -e:1) v:{ ->5 
7  <1> entersub[t2] vKS/TARG ->8  
-  <1> ex-list K ->7    
5   <0> pushmark s ->6   
-   <1> ex-rv2cv sKPRMS/4 ->-  
6    <0> padsv[$func:1,2] s ->7 

... 실제로 - <1> ex-rv2cv sKPRMS/4 ->-에 대한 플래그에 약간의 차이가 기다립니다. 어쨌든, 그것들은 중요하지 않은 것처럼 보입니다. 그리고 두 형태 모두 똑같이 행동합니다.

하지만 양식 $func->()를 사용하는 것이 좋습니다 : 나는 더 우아한으로이 구문을 인식, 당신은 실수로 괄호 (&$func 작품을 사용하는 것을 잊지 있지만 수 없습니다 현재 당신이 무엇을하지 않은 기능을 볼 수 @_ 보통 원한다.)

+2

+10 @ '의 가시성을 언급합니다. – jm666

+0

perl -MB = Deparse의 결과는 조금 더 읽기 쉬울 수도 있고, 두 변형 모두 동일하게 간주된다는 것을 보여줄 수도 있습니다. Deparse는 $ func ->()를 & $ func()로 변환합니다. –

관련 문제