web-dev-qa-db-ja.com

Perlにあるオブジェクトのタイプを見つける方法は?

Perlで処理しているオブジェクトタイプを見つけるにはどうすればよいですか? Perl -dを使用してデバッガーに入ろうとしましたが、どうすればよいかわかりません。同様に、各オブジェクトで使用できるメソッドを簡単に確認する方法が欲しいのですが、それをどのように行うことができますか?

30
John

所有しているオブジェクトのタイプを通知する標準的な方法は、 ref または Scalar::Util::blessedのいずれかです。あなたが知っているオブジェクトが祝福されている場合、それらは同じ情報を返します。

my $class1 = blessed( $obj );
my $class2 = ref $obj;

しかし、refはblessされていないハッシュに対して 'HASH'を返しますが、blessedはそのゲームのプレイを拒否します。

メソッドのリストについては、Perlオブジェクトの祝福されたポインタースタイルの場合、自分でコードを作成するのは簡単です。以下のコードは私にはかなりうまくいきます。関数を定義するパッケージにマッピングされた関数の名前(指定された名前の「CODEスロット」をとる関数)を返します。

sub class_methods { 
    use Class::ISA;
    my $obj = shift;
    return unless ref( $obj );
    my %meth_names;
    foreach my $anc ( Class::ISA::self_and_super_path( ref $obj ), 'UNIVERSAL' ) {
        my $stash = \%{"$anc\::"};
        my @funcs 
            = grep { m/^[_\p{Alpha}]/                # begins with _ or alpha
                   && !exists $meth_names{$_}        # no clobbering
                   &&  defined *{$stash->{$_}}{CODE} # has a filled CODE slot
                   } keys %$stash
            ;
        # assign to the "hash slice", keyed by all the entries in @funcs
        # the value of $anc repeated as many times as elements in @funcs.
        @meth_names{@funcs} = ( $anc ) x @funcs;
    }
    return %meth_names;
}
  • これはかなり複雑なオブジェクトでも機能しますが、所有するパッケージに多くの生成されたコードが含まれている場合、ジェネレーターがコードポインターをスタックしているパッケージを知ることはそれほど役に立ちません。コードを生成しました。

  • これが事実である場合、 Data::Dumper を含み、$Data::Dumper::Deparseを1に設定するなど、コードの実行からコードを取得する可能性があります so:(local $Data::Dumper::Deparse = 1;)そして、次のようにコードポインタをダンプします:say Dumper( $code_ref );

  • WO N'Tは、AUTOLOADメソッドによってまだ作成されていない有効なメソッドに対しては機能しません。リストにそれらが表示されている場合、オブジェクトはより多くのことを行う可能性がありますが、オブジェクトのすべての機能はわかりません。

  • 「基本クラス」UNIVERSALが含まれているのは、そのクラスにオブジェクトが使用できる動作が含まれているためです。

幸運を。

30
Axeman

Scalar :: Utilblessed 関数は、blessされた参照(オブジェクト)のパッケージ名を通知します。

使用可能なメソッドを確認するには、そのパッケージのドキュメントを参照してください。または、 Class :: MOP :: Class のようなものを使用して、メタクラスをインスタンス化し、メタクラスに含まれるメソッドに関する内省的な情報を取得できます。

5
friedo

完全を期すために、デバッガのごく簡単な紹介を示します。

Perl -d your_program

盗賊の下でそれを開始します。最初の実行可能な行で制御を取得します(useステートメントなどはこの時点ですでに実行されています)。

's'は次の行に進みます。 「s」を入力したら、単にReturnキーを押して繰り返すことができます。 「s」は、関数/サブルーチン/メソッドにステップダウンします。戻るまでステップ実行を続けるか、「r」コマンドを入力して残りの関数を実行し、呼び出しの直後に戻ります。

サブルーチンをステップオーバーする場合、つまり、サブルーチンを実行して、ステップインして戻る必要なしに戻る場合は、「n」を使用します。最初の「n」の後のキャリッジリターンも「n」を続けます。

停止したい行がわかっている場合は、「b」コマンド-b linenumber-を使用してブレークポイントを設定し、次に「c」でブレークポイントに到達するまで続行します。 'c'してブレークポイントに戻るたびに、再び停止することに注意してください。ブレークポイントをオフに戻すには、「B linenumber」を使用します。

それで、あなたがこのようなものになっていると仮定しましょう:

my $obj = complex_function_returning_unknown_thing;

デバッガーはこの行を表示しました。「これはまだ実行していませんが、次に実行することです」と表示されています。 'n'を入力してサブルーチンを実行し、 'x'コマンドを使用してオブジェクトを確認します: 'x $ obj'。大きい場合は、ページャーを介して出力を実行する「| x $ obj」と言うことができます。オブジェクトのメソッドを確認するには、「m $ obj」を使用します。

デバッガーには他にも多くの機能がありますが、実際にこの種の目的に使用できます。コードから取得するオブジェクトのタイプを確認し、取得したオブジェクトにどのメソッドがあるかを確認する必要があります。

オブジェクトを 'x'にしてから、オブジェクトが祝福されているクラスのソースを調べて、あなたがしていることとは対照的に、あなたがすべきを実行することを確認するのがより便利ですできるする。とにかく、 'x'コマンドはData :: Dumperと交差する 'print ref($ obj)'です。

3
Joe McMahon

Perlでの反射を探しています。私は引用符なしで「Perl Reflection」をググっただけで、これが思い付きました:

http://coding.derkeiler.com/Archive/Perl/perl.beginners/2004-10/0291.html

Edit:そしてこれ: http://markmail.org/message/i5mzik56ry4zoxxq

編集:そして、これ: http://en.wikipedia.org/wiki/Reflection_(computer_science)#Perl

0
Hamish Grubijan