2016-09-20 4 views
6

다음 코드를 살펴 보시기 바랍니다 : 그게 뜻 이죠,펄은`정의 '와`미확정'서브 루틴 범위는

use strict; 
use warnings; 


print "subroutine is defined\n" if defined &myf; 
myf(); 

sub myf 
{ 
     print "called myf\n"; 
} 

undef &myf; 
#myf(); 
print "now subroutine is defined\n" if defined &myf; 

출력은 첫 번째 print 문을 인쇄 할 수 있습니다

subroutine is defined 
called myf 

입니다 인터프리터 (또는 컴파일러?)가 더 멀리 보이고 서브 루틴 정의를 보았습니까? 그렇다면 undef &myf;이 두 번째 print 문으로 표시되지 않는 이유는 무엇입니까? 범위로 할 필요가 있지만, 함께 시간런타임을 컴파일되지 않습니다

감사

+4

'undef'는 런타임에 실행하는 코드이기 때문에'sub'는 정의이고 컴파일 타임에 발생합니다. – Sobrique

답변

10

. 다음은 간단한 설명입니다.

Perl 인터프리터는 처음에 코드를 스캔하고 use 문 또는 BEGIN 블록을 따릅니다. 이 시점에서 모든 sub을보고 해당 패키지에 기록합니다. 이제 기호 표에 &::myf이 생겼습니다.

컴파일 시간이 프로그램 끝에 도달하면 런타임으로 전환됩니다.

그 시점에서 실제로 코드를 실행합니다. &myf이 정의 된 경우 첫 번째 print 문이 실행됩니다. 우리는 그것이 컴파일 시간에 설정 되었기 때문에 그것을 알 수 있습니다. Perl은 그 함수를 호출합니다. 모든 것이 잘됩니다. 이제 너 undef 그 엔트리가 기호 테이블에있다. 그것은 런타임에도 발생합니다.

그 후 defined &myf은 false를 반환하므로 인쇄되지 않습니다.

코드에 myf()이라는 두 번째 호출이 있지만 주석 처리했습니다. 주석을 제거하면 에 대한 불평 할 것입니다. 정의되지 않은 서브 루틴 & main :: myf가이라고합니다. 그것은 일어난 일에 대한 좋은 암시입니다.

사실 코드에서 앞으로 또는 뒤로 보지 않습니다. 그 시간에 코드를 이미 스캔했습니다.


다른 스테이지는 in perlmod으로 설명됩니다.

실제로 기능을 구현하는 데는 많은 경우가 없다는 점에 유의하십시오. 나는 네임 스페이스를 수동으로 정리하고 싶지 않다면 왜 그걸 제거 할 것인지 모르겠다.

+0

좋은 대답이지만, 왜 서브 루틴이 정의되기 전에'myf;'(또는'main :: myf;') 문을 쓸 수 없는지 설명하지 못합니다. – Borodin

+1

@Borodin : 컴파일 타임에 compiller는'myf' 또는'main :: myf' barewords가 서브 루틴임을 ('use strict'를 끄면 :'Bareword "myf"는 허용되지 않는 반면 "strict subs" 서브 루틴이 정의 된 후에는 심볼 테이블에'& :: myf'가 있고, 정의 이후에'myf' 또는'main :: myf'를 쓸 수 있습니다. 당신이 서브 루틴을 호출하기를 원하는 펄을 보장하기 위해서 bearword :'myf()'후 괄호 –

+0

@Borodin 질문에 포함되지 않았다.) – simbabque