2

それで、最近、Perl と Moose を使用するプロジェクトに取り組んでいます。Moose が MOP 上に構築されていることは理解しています。私は MOP にあまり詳しくなく、理解できないことに遭遇しました。理論的な説明を使用できます。モジュールnamespace::autocleanのドキュメントは次のとおりです。

SYNOPSIS
    package Foo;
    use namespace::autoclean;
    use Some::Package qw/imported_function/;

    sub bar { imported_function('stuff') }

    # later on:
    Foo->bar;               # works
    Foo->imported_function; # will fail. imported_function got cleaned after compilation

つまり、私が Moose を使用する前は、オブジェクトのメソッドを呼び出す方法は次のとおりでした: Perl インタープリターは、オブジェクトが bless されたパッケージのシンボル テーブルでそのメソッドを検索します (見つからない場合は、@ISA相続など)。パッケージ内からインポートされた関数を呼び出す方法は、パッケージのシンボル テーブルで関数の名前を検索することでした。私がこれまでに知っている限り、どちらの方法でも同じシンボル テーブルを意味するため、この動作は不可能なはずです。

ソースの最初の検査は生産的ではありませんでした。大まかに言えば、Moose、MOP、および namespace::autoclean を使用すると、この種のトリックが可能になるという点で何が違うのでしょうか?

編。特に明確にするために、私use namespace::autoclean

CHECK { undef *Foo::imported_function }

を見つける場所がわからないため、ドキュメントに記載されているFoo->bar;呼び出しがクラッシュします。Foo->barimported_function

4

2 に答える 2

3

それは実際には非常に簡単です。為に

some_sub()

some_subコンパイル時に解決されます。為に

$o->some_method()

some_method実行時に解決されます。の値に依存するため、コンパイル時に行うことはできません$o

于 2013-02-04T18:59:07.777 に答える
1

ここには非標準的なものは何もありません。この線

use Some::Package qw/imported_function/;

imported_functionは現在のパッケージにインポートされるためFoo::imported_function、 と同じサブルーチンSome::Package::imported_functionです。Some::Packageこれは、から継承しExporterてシンボル テーブルの必要な操作を行うことを前提としています。

呼び出しはメソッド呼び出しなのでFoo->bar、 と同じFoo::bar('Foo')です。ここでの唯一の特別な点は、import関数 fromによって実行された魔法がExporter、コンパイル時間の最後に によって元に戻されることnamespace::autocleanです。

このモジュールのコードは見ていませんが、パッケージのシンボル テーブルは単なるハッシュ (シンボル テーブル ハッシュのstashとして知られています) であるため、ある時点でその状態を保持し、後で復元するのは簡単です。したがって、ロード時にシンボルテーブルのスナップショットを取得し、コンパイル時間の最後にその状態を復元すると思います。これは、ブロックのように動作するブロックで便利に実行できますが、コンパイルの最後と実行の開始前に実行されます。namespace::autocleanCHECKBEGIN

于 2013-02-04T18:29:03.497 に答える