2010-06-08 13 views
6

Soyut bir My :: Object ve somut rol uygulamalarını tanımladığımı söyle. :: :: :: :: :: :: :: :: ::: Sürdürülebilirlik nedenlerinden ötürü, nesne türüne bakan ve rolleri uygulayan sabit kodlanmış bir tablonun olmasını istemiyorum.Varolan Moose rolünü çalışma zamanında bir sınıfa nasıl yazarım?

has => 'id' (isa => 'Str', required => 1); 

sub BUILD { 
    my $self = shift; 

    my $type = $self->lookup_type(); ## Returns 'TypeB' 
    {"My::Object::$type"}->meta->apply($self); 
} 

beni aşağıdakileri yaparak uygulanan My :: Nesne :: TypeB rolü ile My :: Nesne olsun Letting: Bir DWIMmy örnek olarak, My :: Nesne bu yöndeki şey arıyorum:

my $obj = My::Object(id = 'foo') 

İstediğim şeyi yapacak mıyım yoksa tamamen yanlış yolda mıyım?

Düzenleme: Bunu çok basitleştirdim; Nesneyi hazırladığımda türü bilmek istemiyorum, nesnenin türünü belirlemesi ve doğru rolün yöntemlerini uygun şekilde uygulamasını istiyorum. Bunu daha net hale getirmek için sorumu düzenledim.

cevap

7

Denediniz mi?

$perl -Moose -E' 
    sub BUILD { my ($self, $p) = @_; my $role = qq[Class::$$p{role}]; $role->meta->apply($self) }; 
    package Class::A; use Moose::Role; has a => (is => q[ro], default => 1); 
    package main; say Class->new(role => q[A])->dump' 

Verim:

$VAR1 = bless({ 
      'a' => 1 
      }, 'Class::MOP::Class::__ANON__::SERIAL::1'); 

İstediğin gibi görünüyor. Oose.pm içinde kodu temizledik.Arama:

package Class; 
use Moose; 
sub BUILD { 
    my ($self, $p) = @_; 
    my $role = qq[Class::$$p{role}]; 
    $role->meta->apply($self); 
} 

package Class::A; 
use Moose::Role; 

has a => (is => 'ro', default => 1); 

package main; 
Class->new(role => 'A'); 
+0

Hayır, yapmadım. -> Meta belgelerini doğru bir şekilde anladığımı ve yanlış yoldan aşağı inmediğimi anlatan en iyi uygulamalardan biriydi. – Oesor

+0

Moose ve Perl genel olarak deneysel bir dil olma konusunda çok iyidir. Bir sorunuz varsa, deneyin ve sonuçların ne olduğunu görün. Eğer sonuçları anlamadıysanız * o zaman…… kendinizi hipotezinizi onaylamak/reddetmek için bir başkasını beklemek için çok fazla zaman kazandıracaksınız. – perigrin

4

Kullanım MooseX::Traits, o zaman sadece çağrı zamanında uygulanabilecek özelliği içine rol dönecek:

# Where Class is a class that has `use MooseX::Traits`; 
    # And TypeB is a simple role 
    Class->new_with_traits(traits => [qw/TypeB/]) 

    # or even the new, and now preferred method. 
    Class->with_traits('TypeB')->new(); 
+0

Sorumu açıklamak için sorumu düzenledim. Anlayabildiğim kadarıyla, MooxeX :: Traits nesnenin nesne örneğinde bilinmesi gereken bir tür gerektirir. Nesnenin türünü belirlemesini ve API'nin bir parçası olmasını gerektirmektense gerekli rolü uygulamasını istiyorum. – Oesor

1

soru güncellemesinden sonra ben o başka bir çatlak vereceğiz: with() olduğunu sadece bir işlev çağrısı.

package Class; 
use Moose; 

BEGIN { 
    with (map "MyObject::$_", qw/TypeA TypeB/); 
} 

Ayrıca, __PACKAGE__ sabit perl ile cari paketini referans alabilir.

İlgili konular