2013-08-13 9 views
7

Gibt es eine Möglichkeit festzustellen, ob eine Subroutine als Methode (mit @ISA probing) oder als einfache Subroutine aufgerufen wird? Vielleicht mit einer Art von Erweiterungsmodul super- caller()?Wie kann ich in Perl feststellen, ob eine Subroutine als Methode aufgerufen wurde?

Zum Beispiel gegeben

package Ad::Hoc; 

sub func() { ... } 

Wie kann func() zwischen den beiden folgenden Anrufungen unterscheiden:

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

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

(ich weiß, der Wunsch, dies zu tun, ist eine Likely Anzeige Poor Design ™.)

Antwort

10

Sehen Sie, ob Devel::Caller hilft. Ich änderte den Code func auf ein Objekt aufzurufen, und es scheint, mit perl 5.14.3 (und 5.24.0) auf meinem Mac zu arbeiten:

called_as_method($level)

called_as_method returns true, wenn das Unterprogramm bei $level genannt wurde als eine Methode.

#!/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(); 

Ausgang:

method 
function
+3

Sie müssen dies jedoch nur verwenden, wenn die Methode eine variable Anzahl von Argumenten akzeptiert. Andernfalls können Sie einfach die Größe von '@ _' überprüfen. – ikegami

+0

+1 sehr vielversprechend. Ich bekomme einen fatalen "pushmark or pad" -Fehler, wenn ich '$ gesegnet-> func' mit' called_as_method() '(5.18.0, PadWalker-1.96, D :: Caller-2.06), aber den" package method "-Aufruf versuche funktioniert perfekt, wie Sie oben illustrieren. – pilcrow

+0

@ikegami, einverstanden. Das ist technische Neugier, die aus einem Problem herausgesponnen wurde, das eigentlich gar nicht hätte zugelassen werden dürfen. – 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

Wie funktioniert diese diskriminieren Ad :: hoc-> func von func ('Ad Hoc ::') oder o- $> func() von func ($ o)? – pilcrow

+1

@pilcrow, 'ref 'Ad :: Hoc'' wird nicht zurückgegeben" "Ad :: Hoc'' ... – kjprice

+0

@pilcrow, ja, für Sie sind der zweite Fall, ich weiß es nicht. Wenn Sie das schreiben, sollten Sie vielleicht einfach eine zusätzliche Flagge weitergeben. – kjprice

Verwandte Themen