2009-11-01 9 views
5

は、次の点を考慮してください問題:: NonMooseクラス

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' 
     ]; 

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

これを解決する最良の方法は何ですか? @ISABEGINブロックで手動調整すると、MooseX::NonMooseに干渉しますか?これがあるかどうかを知るためにムース内部に関する

package MyApp::CGI; 

use Moose; 
use MooseX::NonMoose; 

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

私は十分知っていない(または何かを、本当に):

は、以下の編集が動作しているように見えますが、私はそれが不快見つけます良い考え。

+5

BEGIN {extends ...}。 – jrockway

+1

(BEGINの同義語としての "use"は一般的な反パターンです。) – jrockway

+0

jrockway:答えではなく、コメントでなければなりません。 – ysth

答えて

5

私はそれはあなたが必要なものを正確に行いますので、ひどく恐ろしいことuse base 'CGI::Application'; extends 'CGI::Application';を見つけることができません。コンパイル時に

  • @ISAが正確にCGIの使用要件を満たす'CGI::Application'、含ま::アプリケーション::プラグイン:: *
  • ランタイムでは、あなたのクラスはCGI::ApplicationMoose子孫であり、すべてのメリットが得られます(あなたのクラスの構成をムーシーのメタ優位性で設計できる)。 行に、extendsという文で行われる作業(つまり、クラスがMoose::Objectに由来し、メタクラスがインストールされている)に依存する作業が完了した(つまり、クラスでメソッドが呼び出された)ときのみです。

    BEGIN { extends 'CGI::Application' } 
    

    ...あなたがそれを必要とするときからほんの少し前倒しのすべてMooseyメタ良さを取得し、それはいけない場所:jrockwayのソリューションでも動作するはず、と述べ

を定義するために、既にuse Mooseuse MooseX::NonMooseを呼び出していれば、もあとでとなることがあります。

(補遺:今、私は彼らがBEGINブロックに包まれたかのように、すぐに、このような解析され、コンパイル時にキーワードの解析を強制する能力を作成するcomplilational複雑さを考えています例えば、何かの場合のように。 Moose.pmはuse compiletime qw(extends)と宣言しました。確かに文法的に砂糖がいいでしょう)。

+1

'BEGIN'ブロックを使うと動作します。私はjrockawayに++を与えるだろうが、彼は答えに投稿していない。 :) – friedo

+1

Ether:Devel :: BeginLiftはそれを行います。 – jrockway

+0

@jrockway:ああ、一緒に遊ぶ新しいおもちゃ!ありがとう! – Ether