2013-08-13 3 views
7

서브 루틴이 메소드 (@ISA 프로빙)로 호출되는지 또는 일반 서브 루틴으로 호출되는지 여부를 판별하는 방법이 있습니까? 아마도 어떤 종류의 확장 모듈 super-caller()? 어떻게 func() 다음과 같은 두 가지 호출을 구별 할 수 Perl에서 서브 루틴이 메소드로 호출되었는지 어떻게 확인할 수 있습니까?

package Ad::Hoc; 

sub func() { ... } 

을 부여 예를 들어

는 :

Ad::Hoc->func;   # or $obj->func 

Ad::Hoc::func('Ad::Hoc'); # or func($obj) 

(내가 아는 한,이 작업을 수행하는 욕망은 가난한 디자인 ™의 가능성이 표시입니다.)

답변

10

Devel::Caller이 도움이되는지 확인하십시오. 나는 객체에 func를 호출하는 코드를 변경하며 perl 5.14.3 (및 5.24.0) 내 Mac에서 작동하는 것 같다 : $level에서 서브 루틴이

called_as_method($level)

called_as_method returns를 불렀다 경우는 true 방법으로.

#!/usr/bin/env perl 

package Ad::Hoc; 
use strict; use warnings; 

use Devel::Caller qw(called_as_method); 

sub func { 
    printf "%s\n", called_as_method(0) ? 'method' : 'function'; 
    return; 
} 

package main; 
use strict; use warnings; 

Ad::Hoc->func; 
Ad::Hoc::func(); 

출력 :

method 
function
+3

그러나 메서드가 가변 개수의 인수를 허용하는 경우에만이를 사용해야합니다. 그렇지 않으면 단순히'@ _ '의 크기를 검사 할 수 있습니다. – ikegami

+0

+1 매우 유망한. 'called_as_method()'(5.18.0, PadWalker-1.96, D :: Caller-2.06)로'$ blessed-> func'을 시도하면 치명적인 "pushmark or pad"오류가 발생하지만 "package method"호출 위에서 설명한 것처럼 완벽하게 작동합니다. – pilcrow

+0

@ ikegami, 동의. 이것은 처음부터 허용되어서는 안되는 문제에서 벗어난 기술적 인 호기심입니다. – pilcrow

-2
package Ad::Hoc; 

sub foo { 
    my $self = shift; 
    if(ref($self) ne 'Ad::Hoc') { 
     unshift @_, $self; 
     undef $self; 
    } 

    if($self) { 
     # I'm a method 
    } else { 
     # I'm a sub 
    } 
} 
+0

어떻게이 차별 광고 :: Hoc-> FUNC FUNC에서 FUNC ('광고 :: 특별'), 또는 $ O-> FUNC()에서 ($ o)? – pilcrow

+1

@pilcrow,'ref 'Ad :: Hoc는''Ad :: Hoc ''을 반환하지 않을 것입니다 ... – kjprice

+0

@pilcrow, 네, 두 번째 경우이기 때문에 잘 모르겠습니다. 만약 당신이 그것을 쓰고 있다면, 아마 당신은 단지 추가적인 깃발을 통과해야합니다. – kjprice

관련 문제