런타임에 PERL 기능이 존재하는지 어떻게 결정할 수 있습니까?
-
10-07-2019 - |
문제
Perl에서 테스트 프레임 워크 작업을하고 있습니다. 테스트의 일환으로, 주어진 테스트에 대해 전제 조건 또는 도전 검사를 추가해야 할 수도 있지만 반드시 모든 것이 아닙니다. 내가 지금까지 가지고있는 것은 다음과 같습니다.
eval "&verify_precondition_TEST$n";
print $@ if $@;
불행히도,이 출력은 "정의되지 않은 서브 루틴 및 verify_precondition_test1이 호출됩니다 ..."함수가 존재하지 않는 경우.
함수를 호출하기 전에 함수가 존재하는지 미리 결정하려면 어떻게해야합니까?
해결책
정의 된 :
if (eval "defined(&verify_precondition_TEST$n)") {
eval "&verify_precondition_TEST$n";
print $@ if $@;
}
else {
print "verify_precondition_TEST$n does not exist\n";
}
편집하다: 흠, 나는 의문의 여지가있는 것처럼 평가 만 생각했지만 레온 팀 머스와의 상징적 인 참고 문헌으로 당신은 할 수 없었습니다.
if (defined(&{"verify_precondition_TEST$n"}) {
&{"verify_precondition_TEST$n"};
print $@ if $@;
}
else {
print "verify_precondition_TEST$n does not exist\n";
}
엄격히?
다른 팁
Package::Name->can('function')
또는
*Package::Name::function{CODE}
# or no strict; *{ "Package::Name::$function" }{CODE}
또는 예외로 살아 가십시오. Eval에서 함수를 호출하고 $@가 설정되면 함수를 호출 할 수 없습니다.
마지막으로, 당신이 이것을 직접 쓰는 대신 시험 :: class를 원할 것 같습니다.
편집하다: defined &function_name
(아니면 그 no strict; defined &{ $function_name }
다른 답변에서 언급했듯이 변형)는 가장 좋은 방법으로 보입니다. Universal :: Can은 (스타일 적으로) 메소드로 부르는 것에 가장 적합하며 Perl이 원하는 것을 구문을 줄 때 기호 테이블로 엉망이되는 이유는 무엇입니까?
학습 ++ :)
sub function_exists {
no strict 'refs';
my $funcname = shift;
return \&{$funcname} if defined &{$funcname};
return;
}
if (my $subref = function_exists("verify_precondition_TEST$n") {
...
}
레온의 접근 방식을 사용했지만 여러 패키지가 있으면 실패했습니다. 나는 정확히 왜 그런지 확실하지 않습니다. 나는 그것이 네임 스페이스 사이의 범위 전파와 관련이 있다고 생각합니다. 이것이 제가 생각해 낸 해결책입니다.
my %symbols = ();
my $package =__PACKAGE__; #bring it in at run-time
{
no strict;
%symbols = %{$package . "::"}; #See Symbol Tables on perlmod
}
print "$funcname not defined\n" if (! defined($symbols{$funcname});
참조 :
__패키지__ perlmod 페이지에서 참조.
패키지/__ 패키지 __Perl Training Australia에 대한 참조.