2013-08-13 4 views
7

サブルーチンが(@ISAプロービングを使用して)メソッドとして呼び出されるか、プレーンなサブルーチンとして呼び出されるかを判断する方法はありますか?多分拡張モジュールsuper-caller()の何らかの種類で?例えばPerlでは、サブルーチンがメソッドとして呼び出されたかどうかをどのように判断できますか?

は、以下の二つの呼び出し間func()を区別することができますどのように

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上で動作するようです:

called_as_method($level)

called_as_method returns$levelでサブルーチンが呼び出された場合方法として。

#!/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またはpad "という致命的なエラーが出ますが、" package method "上記のように、完全に機能します。 – pilcrow

+0

@ikegami、agree。これはおそらく最初に許可されていないはずの問題から作られた技術的好奇心です。 – 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

関連する問題