2009-06-24 8 views
3

私は本質的に静的な関数を書いています。クラス名に沿って渡すTemplate Toolkitにプラグインしたいと思っています。不可欠で、それは通常のサブルーチンとクラスメソッドの両方で動作するPerlサブルーチンを書くにはどうすればよいですか?

ClassName->function($args..) 

をやっているが、私は両方のケースを処理するための適切な方法は何ですか?それは

sub function { 
} 

ClassName::function($args..) 

のような何かをしたいですか

+0

なぜClassName :: function($ args ..)のようなことをしたいのですか? –

+1

これは本当にクラスに依存しない静的/ヘルパーメソッドですか? – Timmy

答えて

7

一般にはありません。 subは、メソッドとして呼び出されるように記述されているか、そうでないと記述されています。

File::Spec::Functionsが、この状況をどのように処理するかは、引数名の前にパッケージ名を付けることで確認してください。

今、非常に具体的な、限定された場合は、あなたが行うことができます:あなたのサブの最初の行として

shift if $_[0] eq __PACKAGE__; 

subは、クラスメソッドとして呼び出された最初の引数を破棄します。

+2

+1。これは、各関数が固定数の引数を取る場合に安全になります。この場合、OO呼び出し構文が使用されるかどうかは、予想以上に1つのパラメータがあるかどうかによって決まります。 (「ClassName :: function( 'ClassName');」を呼び出すと偽陽性が発生します) –

+0

@j_random_hackerありがとうございます。 –

4

Template Toolkitは、OOを使用するためのプラグインを必要とするため、そのインタフェースを提供する方法はありません。機能的なインターフェースが必要な場合は、いくつかのオプションがあります。

Perlは関数とメソッドを区別しません。主な違いは、メソッドの呼び出し構文では、最初の引数としてオブジェクト参照(または呼び出された方法に応じてクラス名)が暗黙的に含まれている点です。関数呼び出しの構文を使用して、手動で指示対象を指定することができます。

ClassName::function('ClassName', @args); 

しかし、それは面倒です。より洗練されたソリューションは、2つのサブシステムに分割することです。例えば

package ClassName; 

sub function { 
    # do something 
} 

sub method { 
    my $class = shift; 
    function(@_); 
} 

この関数は、メソッドのラッパーでもあります。 Sinanが指摘しているように、File :: Specは、OOインターフェイスと機能インターフェイスの2つのモジュールを作成することでこれを行います。ここで

+1

または、Perlにラッピングをさせてください: "package ClassName :: Functional; sub AUTOLOAD {厳密な参照は必要ありません} ClassName - > $ AUTOLOAD(@_);}" –

+1

@j_random_hacker:厳密な参照は厳密な "refs"それが厳密な参照の下で許可されているので、必要でないことを除いて厳密なsubsの下で失敗します。 $ AUTOLOADは完全修飾されているので、$ AUTOLOAD =〜s /.* :: //が必要です。またはあなたは無限再帰を得る。 – ysth

+0

@ysth:ありがとう! (非常に小さなコードのバグが多いので、うわー...)なぜ、 " - > $ method"が厳密な 'refs'なしで許可されているのか?ちょうど別の任意のPerlの不一致? –

6

Sinan'sAlan's答えを組み合わせた、より安全なバージョンであり、かつ:

  • は、メソッドが派生オブジェクト
  • から呼び出されている可能性がメソッド呼び出しとしてClassName::function("ClassName")を誤解しないだろうハンドル

コード:

if (@_ == $nArgsExpectedForThisFunc + 1) { 
    $_[0] eq __PACKAGE__ || UNIVERSAL::isa($_[0], __PACKAGE__) || die; 
    shift; 
} 

これには、期待する引数の数を知っている必要があります。そうでない場合、最初の引数は、メソッドとして呼び出されたときに送信される可能性のある許容値と区別できます(たとえば、最初の引数が配列参照でなければならない場合)。

+1

+1ニースのコンボですが、マイケル・カーマンのラッパーのアイデアも好きです:http://stackoverflow.com/questions/1038975/perl-function-with-with-without-class/1039085#1039085 –

関連する問題