2010-10-22 8 views
6

Geyik nesnesi için bir modül yazıyorum. Bu nesneyi kullanan bir kullanıcıya (veya kendime ...) istediği gibi anında bazı alanlar eklemesine izin vermek istiyorum. Bu alanları önceden tanımlayamıyorum, çünkü ne olacağını bilmiyorum.Moose nesnelerine nasıl esnek bir şekilde veri ekleyebilirim?

# $obj is a ref to my Moose object  
$obj->extra()->{new_thingie}="abc123"; # adds some arbitrary stuff to the object 
say $obj->extra()->{new_thingie}; 

Bu işleri: Kullanıcıların sadece o karma malzeme koymak böylece

Şu anda sadece, rw şeklinde ayarlanmış olan tip hashref ekstra adlı tek bir alan ekledi. Ama ... bu yaygın bir uygulama mı? Başka (muhtemelen daha zarif) fikirler var mı?

Not Bunu genişleten başka bir modül oluşturmak istemiyorum, bu sadece eklemek istediğim anında kullanılabilecek şeyler için.

cevap

6

muhtemelen yerli özelliklerin üzerinden bu yapardı istisna ve mesaj sınıfları için göze çarpan veriler.

+0

+1 Bu gerçekten harika! –

+0

Varolan olmayan bir alanı okumaya (ayarlamama) izin verirse erişimciyi değiştirebilir miyim? –

+0

'custom_field' erişimcisini yaklaşık bir düzenleyici ile doldurabilir, arjları kontrol edebilir ve 'has_custom_field' öğesi false değerini döndürür. – phaylon

4

Eğer dersi değişmez yapmamışsanız (bunu yapmamak için performance penalty varsa, sınıf tanımlarını değiştirme konusunda endişelerimin yanı sıra), bunun için meta sınıfını alabilmeniz gerekir. nesne ($meta = $object->meta kullanarak) ve Class::MOP::Class içinde add_attribute yöntemini kullanarak.

#!/usr/bin/perl 

package My::Class; 

use Moose; 
use namespace::autoclean; 

package main; 

my $x = My::Class->new; 
my $meta = $x->meta; 
$meta->add_attribute(
    foo => (
     accessor => 'foo', 
    ) 
); 

$x->foo(42); 

print $x->foo, "\n"; 

my $y = My::Class->new({ foo => 5 }); 
print $y->foo, "\n"; 

Çıktı:

42 
5
+0

+1 İlginç. Teşekkürler. Genellikle sınıfı değişmez olarak yapıyorum (Moose en iyi uygulamalarını takip ederek). –

3

sonra değil, tüm sınıfa bir nesneye bir yöntem eklemek MooseX::SingletonMethod gibi bir şey de bakabilirsiniz istiyorum Sadece durumda.

E.g.

use 5.012; 
use warnings; 

{ 
    package Foo; 
    use MooseX::SingletonMethod; 
    sub bar { 'bar' }  # method available to all objects 
} 

my $foo = Foo->new; 

$foo->add_singleton_method(baz => sub { 'baz!' }); 

$foo->baz;  # => baz! 

Böylece yöntem baz yukarıda yalnızca nesne $foo için olup sınıf Foo eklenir.

Hmmm ... Acaba MooseX :: SingletonAttribute uygulayabilir miyim?


Bazı önceki SO MooseX::SingletonMethod kullanarak cevap:

Ve belki kullanımı ve/veya ilgi de bu blog yazısı: Easy Anonymous Objects

/I3az/

Bu isteğe bağlı ekleyerek olduğu gibi şeyler için

my $val = $obj->custom_field('foo');   # get field value 
$obj->custom_field('foo', 23);     # set field to value 

$obj->has_custom_field('foo');     # does a specific field exist? 
$obj->has_custom_fields;      # are there any fields? 

my @names = $obj->custom_fields;    # what fields are there? 
my $value = $obj->delete_custom_field('foo'); # remove field value 

yaygın bir kullanım örneği: Aşağıdaki gibi bu kullanırsınız

has custom_fields => (
    traits  => [qw(Hash)], 
    isa  => 'HashRef', 
    builder => '_build_custom_fields', 
    handles => { 
     custom_field   => 'accessor', 
     has_custom_field  => 'exists', 
     custom_fields  => 'keys', 
     has_custom_fields => 'count', 
     delete_custom_field => 'delete', 
    }, 
); 

sub _build_custom_fields { {} } 

bir nesne üzerinde:

+0

+1 Teşekkürler, MooseX :: SingletonMethod hakkında bilgi edinmek için iyi. –