5

次の点を考慮してください。

package MyApp::CGI;

use Moose;
use MooseX::NonMoose;
use Data::Dumper;

extends 'CGI::Application';

BEGIN { 
    print "begin isa = " . Dumper \@MyApp::CGI::ISA;
};

print "runtime isa = " . Dumper \@MyApp::CGI::ISA;

... 

これをコンパイルしたときの出力は次のとおりです。

begin isa = $VAR1 = [
          'Moose::Object'
        ];
runtime isa = $VAR1 = [
          'CGI::Application',
          'Moose::Object'
        ];

なぜ私は気にするのですか?useCGI::Application::Plugin::* クラスを実行しようとするとCGI::Application、コンパイル時にすでに継承していると想定されるためです。add_callbackプラグイン クラスは、私のクラスのクラス メソッドとして呼び出そうとしますが、@ISAまだ設定されていないためできません。

これを解決する最善の方法は何ですか? @ISAブロックを手動で微調整BEGINすると干渉しMooseX::NonMooseますか?

編集

以下は機能しているように見えますが、不快だと思います。

package MyApp::CGI;

use Moose;
use MooseX::NonMoose;

use base 'CGI::Application';
extends 'CGI::Application';

これが良いアイデアかどうかを知るには、Moose の内部構造について十分に (または実際には何も) 知りません。

4

1 に答える 1

5

use base 'CGI::Application'; extends 'CGI::Application';それはあなたが必要とすることを正確に行うので、私はひどく恐ろしいとは思いません:

  • コンパイル時に、@ISAが含まれます'CGI::Application'。これは、CGI :: Application :: Plugin::*の使用要件を正確に満たします。
  • 実行時には、クラスはCGI :: ApplicationのMooseの子孫であり、その後のすべての利点があります(Mooseyメタの良さでクラスの構成を設計できる)。次の行に遭遇した後でのみ、ステートメントによって実行された作業に依存する作業が実行されます(つまり、クラスでメソッドが呼び出されます) 。つまり、クラスの子孫であり、メタクラスがインストールされています。extends 'CGI::Application'extendsMoose::Object

そうは言っても、jrockwayのソリューションも機能するはずです。

BEGIN { extends 'CGI::Application' }

...必要なときにすべてのMooseyメタの良さをスケジュールより少し早く取得します。すでに呼び出して定義するために、スケジュールよりも早くなりすぎないようにする必要があります。use Mooseuse MooseX::NonMooseextends

(補遺:ブロックにラップされている場合など、コンパイル時にキーワードの解析を強制する機能を作成することの複雑さについて考えていBEGINます。たとえば、Moose.pmが宣言した場合などですuse compiletime qw(extends)。確かに構文解析の良い部分になるでしょう。)

于 2009-11-01T05:09:39.517 に答える