2012-08-15 6 views
3

현재 디버깅하는 동안, 나는 내 코드에어디서나 내장형처럼 호출 할 수있는 서브 루틴을 정의 할 수 있습니까?

carp Dumper \@foo, \%bar; 

문을 삽입하고 정기적으로 CarpData::Dumper가 현재 패키지에 가져올 수 없습니다하는 문제로 실행하는 경향이있다. 나는 사방

main::bla \@foo, \%bar; 

을 할 수 그래서 지금

sub main::bla { 
    use Carp; use Data::Dumper; 
    carp Dumper @_; 
} 

하지만 main::은 날 귀찮게 :이 문제를 방지하려면 항상 포함되어있어 중앙 파일에 다음과 같은 하위를 정의했다. 어떤 패키지에도 자동으로 가져 오는 글로벌 패키지와 같은 것이 있습니까 (실제로는 모든 곳에서 가져온 내장 함수와 비슷합니다).

+1

'use'는 컴파일 타임 지시어입니다. 다시 말해, 항상 포함되어있는 일부 모듈에서 '사용'을 사용하면이 모듈도 항상 포함됩니다. 그리고 호출되지 않을 수도있는 (예를 들어, 조건부의 거짓 분기에서) 일부 코드 내에 '사용'을 넣어도 처리되지 못합니다. – raina77ow

+0

@ raina77ow : 멋진 생각. 호출 패키지에 'bla'를 설치하기 위해 일반적으로 포함 된 모듈의'import' 메소드를 납치하려했습니다. 그러나 공통 모듈은 기본적으로'import'를 가지고 있지 않으므로, 다른 모듈이'require' 또는'use'를하면, 다른 모듈은 공통 모듈의 메소드를 호출해야하기 때문에 다시 사용할 필요가 없습니다 어쨌든 (즉,'foo()'대신에'Common :: foo()') 명시 적으로. –

+1

'PERL5OPT' 환경 변수는 항상 특정 모듈을로드하는데 사용될 수 있습니다 :'-MCarp' – toolic

답변

4

당신은 그냥

::bla(\@foo, \%bar); 

이전 일에서, 나는 Ut 패키지에 폴더의 유틸리티 기능을 넣어 사용 호출 할 수 있습니다. 그리고 괜찮 았지만, 생각한 것처럼 코드가 실제로 모듈화 된 것이 아니라는 것을 알았습니다. Ut 함수에 의존하는 각 모듈은 누군가가 문제를 빌드 네임 스페이스로 가져 가면 성공할 수있었습니다.

결국 나는 userequire 문을 단순히 종속성을 문서화하는 것으로 간주했습니다. main에서 구현을 변경하는 대신 라이브러리 모듈에서 호출하는 코드를 변경하는 더 유연한 방법이 있습니다.

예를 들어 하나의 use 문에서이 작업을 수행 할 수 있습니다.

use Ut blah => sub { 
    use Carp; 
    use Data::Dumper; 
    carp Dumper @_; 
}; 

그리고 가져 오기 정의 : 나는 한 번에 많은 코드를 개발하고 있어요 때

sub import { 
    shift; # It's just me 
    my ($name, $impl) = @_; 
    if ($name eq 'blah' && ref($impl) eq 'CODE') { 
     *blah = $_[1]; 
    } 
    ... 
} 

나는 여전히 ut 패턴을 사용합니다. (가끔 U::를 호출하기 때문에) 3-4 문자를 저장하기에 반대하지만

ut:dump_var($var) 

를 작성 상관하지 않습니다.

이제 장기간을 원하지 않고 변수를 버려두는 것이 개발에 유용합니다. 당신이 정말로 이렇게 할 경우, Smart::Comments 지금처럼 작업을 수행합니다

### @foo 
### %bar 

그것을 가지고가는 것은 하나의 use 문이다.

use Smart::Comments; 
+0

':: bla'는 충분히 가깝습니다. ;-) –

+0

'''는'::'의 구식 형태이며'sub U'dump_var {...} ... U'dump_var ($ var)'는 fubar가 아닌지 말할 수 있음을 기억하십시오 구문 형광펜. – mob

+0

@ mob, 나는 결코'''을 사용하지 않았습니다. 나는 항상 그것을 제안한 것을 궁금해했습니다. 정말로 타이핑을 저장하고 싶다면'dv'라고 부르면됩니다 :'U :: dv' – Axeman

1

내보내기가 필요한 다른 패키지를 만드는 것이 더 좋을 수도 있습니다. 좋아요, MyTest.오후 :

package MyTest; 

use strict; 
use Carp; 
use Data::Dumper; 


use base qw(Exporter); 
our @EXPORT = qw(
    debug 
) 

sub debug { 
    carp Dumper @_; 
} 

1; 

그래서 당신은 그럼 그냥 스크립트에서 쓸 수 있습니다 :

use MyTest; 

debug {a => 'b', c => 'd' } 
0

재미있는 사실 : Some symbols 그들은 항상 main 패키지에 자신의 값을 참조하는 마법이다. 이 기호에 서브 루틴을 할당하면 서브 루틴을 패키지에 표시 할 수 있습니다. 당신은 당신의 코드가 미친 유지하고 다음 사람을 운전하려는 경우가 아니면이의

{ 
    package Foo; 

    # special names _ ARGV ARGVOUT ENV INC SIG STDERR STDIN STDOUT 
    sub ENV { print "In main::ENV ...\n" } 
    sub STDIN { print "In main::STDIN ...\n" } 
    sub _ { print "In main::_\n" } 

    # names that begin with^+ upper case letter, or all digits 
    *{^T} = sub { scalar localtime }; 
    *{^Gmtime} = sub { scalar gmtime }; 
    *43 = sub { 42 }; 

    use Data::Dumper; 
    *{^D} = \&Data::Dumper::Dumper; 
} 

{ 
    package Bar; 
    &ENV; 


    STDIN(); 
    print "The time is ", &^T, "\n"; 
    print "In London it is ", &{^Gmtime}, "\n"; 
    print "The answer is ", &43, "\n"; 

    print "\@foo is ", &^D(\@foo); 
} 

없음은 권장되지 않습니다.