2009-11-01 5 views
5

Rozważmy następujący:problem z wstawek w MooseX :: NonMoose klasa

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; 

... 

Wyjście gdy kompiluje się:

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

dlaczego mnie to obchodzi? Ponieważ, gdy próbuję uzyskać use klasę CGI :: Application :: Plugin :: *, oczekuje ona, że ​​dziedziczę już od CGI::Application w czasie kompilacji. Klasa wtyczek próbuje wywołać add_callback jako metodę klasy na mojej klasie, ale nie może, ponieważ moja @ISA nie jest jeszcze skonfigurowana.

Jaki jest najlepszy sposób rozwiązania tego problemu? Czy ręczne poprawianie @ISA w bloku BEGIN koliduje z MooseX::NonMoose?

Edit

Poniższy wydaje się działać, ale uważam, że ofensywa:

package MyApp::CGI; 

use Moose; 
use MooseX::NonMoose; 

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

nie wiem wystarczająco (lub czegokolwiek, naprawdę) o Moose wewnętrznych wiedzieć, czy jest to dobry pomysł.

+5

BEGIN {extends ...}. – jrockway

+1

(Warto zauważyć, że "używanie" jako synonimu dla BEGIN jest powszechnym antypacternem Patrz także: "użyj ok ...") – jrockway

+0

jrockway: to powinna być odpowiedź, a nie komentarz – ysth

Odpowiedz

5

nie znajdę use base 'CGI::Application'; extends 'CGI::Application'; być strasznie okropny bo robi dokładnie to, czego potrzebujesz:

  • w czasie kompilacji, @ISA zawiera 'CGI::Application', który dokładnie spełnia wymagania użytkowe CGI :: Application :: Plugin :: *
  • W czasie pracy twoja klasa jest potomkiem Moose potomka CGI::Application, z wszystkimi wynikającymi z tego korzyściami (możliwość zaprojektowania kompozycji twojej klasy za pomocą metatosego Moosey). Dopiero po napotkaniu linii extends 'CGI::Application' wykonywane są wszelkie prace (tj. Metody są wywoływane w twojej klasie), które opierają się na pracy wykonanej przez instrukcję extends: że twoja klasa pochodzi od Moose::Object i masz zainstalowaną meta-klasę.

Powiedział, że rozwiązanie jrockway powinny również działać:

BEGIN { extends 'CGI::Application' } 

... Gdzie można uzyskać wszystkie meta Moosey dobroć tylko trochę przed terminem od kiedy jest to potrzebne, i nie powinno być zbyt przed terminem, pod warunkiem, że już nazwie use Moose i use MooseX::NonMoose w celu zdefiniowania extends.

(Uzupełnienie:. Teraz mam rozważając complilational zawiłości tworzenia zdolność do zmuszenia analizowania słowa kluczowego w czasie kompilacji, które są przetwarzane natychmiast takimi jak gdyby były one zapakowane w BEGIN bloku np coś jak gdyby Moose.pm zadeklarował use compiletime qw(extends). Byłby to z pewnością miły kawałek cukru syntaktycznego.)

+1

Użycie bloku 'BEGIN' działa. Dałbym ++ do jrockaway, ale nie opublikował go w odpowiedzi. :) – friedo

+1

Ether: Devel :: BeginLift to robi. – jrockway

+0

@jrockway: ooh, nowa zabawka do zabawy! dzięki! – Ether

Powiązane problemy