2009-03-03 8 views
24

perlモジュールが持つすべてのサブルーチンをプログラマチックに検出する最も良い方法は何ですか?これは、モジュール、クラス(@EXPORTなし)、またはその中間のものである可能性があります。Perlモジュールにあるすべてのサブルーチンを発見する最良の方法は何ですか?

編集:以下のすべての方法が動作するように見えます。私はおそらく、Class :: SniffまたはClass :: Inspectorをプロダクションで使用します。しかし、Leonの答えは、no strict 'refs'を使用しなければならないにもかかわらず、疑問のある質問に答えるので、「受け入れられる」とマークされます。 :-) Class :: Sniffは良い選択です。それは多くの思考がそれに入ったように見えます。

答えて

22
sub list_module { 
    my $module = shift; 
    no strict 'refs'; 
    return grep { defined &{"$module\::$_"} } keys %{"$module\::"} 
} 

ETA:インポートしたサブルーチンをフィルタリングしたい場合、あなたはこの

use B qw/svref_2object/; 

sub in_package { 
    my ($coderef, $package) = @_; 
    my $cv = svref_2object($coderef); 
    return if not $cv->isa('B::CV') or $cv->GV->isa('B::SPECIAL'); 
    return $cv->GV->STASH->NAME eq $package; 
} 

sub list_module { 
    my $module = shift; 
    no strict 'refs'; 
    return grep { defined &{"$module\::$_"} and in_package(\&{*$_}, $module) } keys %{"$module\::"} 
} 
+1

これは、モジュールが他のモジュールからインポートしたサブルーチンもリストします。 – innaM

+0

それは問題になるでしょう。 –

+0

2番目の考えでは、アプリケーションによっては重要かもしれません。 –

9

を行うことができ、このを見てください: Class::Sniff

インタフェースではなく、アドホックであります現時点では変更される可能性があります。新しいインスタンスを作成した後は、レポートメソッドを呼び出すことをお勧めします。その後、視覚的に潜在的な問題を探すために、それを調べることができます

my $sniff = Class::Sniff->new({class => 'Some::Class'}); 
print $sniff->report; 

このモジュールは、オブジェクト指向のコードでは「においコードを」プログラマが見つけやすくしようとします。それが何かを報告しても、あなたのコードが間違っているとは限りません。これは、問題があるかどうかを確認するためにコードを少し詳しく見たいということを意味します。

現時点では、Perlのデフォルトの左端、深さ優先の検索オーダーを想定しています。将来的には、これを変更することが(とパス法による回避策があります、この後の詳細。)...

+0

面白そうだが、かなり新しい。私は生産環境でそれを使用することを躊躇します。 –

+2

プロダクション環境でメソッドのリストを取得する必要があるのはなぜですか? – innaM

+1

私はTest :: Classのようなツールのプロトタイプ作成に興味があります。テストされていない他のコードからプロトタイプを作成すると、大きな頭痛になる可能性があります。 :) –

12

Class::Inspectorを:

クラス::インスペクタを使用すると、情報を取得することができますロードされたクラスについてこの情報の大半またはすべては他の方法で見つけることができますが、必ずしもあまりフレンドリーではなく、通常は比較的高水準のPerlの魔法や奇妙で珍しいコードを必要とします。 Class :: Inspectorは、この情報へのより簡単で親しみやすいインターフェースを提供しようとします...

+0

非常に興味深い、私はそれを見てみましょう。 –

+0

私にとっては、すべてのオブジェクトメソッド(継承チェーンのすべて)が必要だったので、この答えはLeonより優れていました。 –

+0

Perlデバッガの内部でClass :: Inspectorを使用することは非常に便利です。 – muriloq

関連する問題