2009-06-29 34 views
12

Moose'da bir sınıf özniteliğine ihtiyacım var. Şu anda söylüyorum:Moose'da bir sınıf özelliği oluşturmanın en iyi yolu nedir?

#!/usr/bin/perl 

use 5.010; 
use strict; 
use warnings; 
use MooseX::Declare; 

class User { 
    has id  => (isa => "Str", is => 'ro', builder => '_get_id'); 
    has name => (isa => "Str", is => 'ro'); 
    has balance => (isa => "Num", is => 'rw', default => 0); 

    #FIXME: this should use a database 
    method _get_id { 
     state $id = 0; #I would like this to be a class attribute 
     return $id++; 
    } 
} 

my @users; 
for my $name (qw/alice bob charlie/) { 
    push @users, User->new(name => $name); 
}; 

for my $user (@users) { 
    print $user->name, " has an id of ", $user->id, "\n"; 
} 

cevap

8

MooseX :: ClassAttribute'u buldum, ama çirkin görünüyor. Bu en temiz yol mu?

#!/usr/bin/perl 

use 5.010; 
use strict; 
use warnings; 
use MooseX::Declare; 

class User { 
    use MooseX::ClassAttribute; 

    class_has id_pool => (isa => "Int", is => 'rw', default => 0); 

    has id  => (isa => "Str", is => 'ro', builder => '_get_id'); 
    has name => (isa => "Str", is => 'ro'); 
    has balance => (isa => "Num", is => 'rw', default => 0); 

    #FIXME: this should use a database 
    method _get_id { 
     return __PACKAGE__->id_pool(__PACKAGE__->id_pool+1); 
    } 
} 

my @users; 
for my $name (qw/alice bob charlie/) { 
    push @users, User->new(name => $name); 
}; 

for my $user (@users) { 
    print $user->name, " has an id of ", $user->id, "\n"; 
} 
+0

Doğru yol budur. Ayrı bir pakette onları tercih ederseniz bir sınıf sınıfı da oluşturabilirsiniz (Classettribute başlıkta – castaway

+0

'un ne yaptığını görün) '' katı 've 'uyarıları kullan' gereksiz 'ile kullanın MooseX :: Declare' kullanın ? –

+0

@Robert P Muhtemelen, bunu yazdığımda MooseX :: Declare kullanmaya başlamıştım. –

2

Dürüst olmak gerekirse, sınıf öznitelikleri için tüm bu sorun için gerekli olduğunu sanmıyorum. Salt okunur sınıf öznitelikleri için, yalnızca bir sabit döndüren bir alt kullanın. okuma-yazma özellikler için pakette basit bir durum değişkeni genellikle hile (ben henüz daha karmaşık bir şey gerekiyordu herhangi senaryolar çalıştırmak değil.) yapar

state $count = 0; 
method _get_id { 
    return ++$count; 
} 

sözlü bir sahip özel blok olabilir 5.10 öncesi uyumluluğa ihtiyacınız varsa kullanılır.

+2

ah, ancak id_pool salt okunur değil, bir erişimci olan gerçek bir sınıf özniteliği istiyorum. Kimlik havuzunu bir veritabanına taşımaya karar verdiğimde kodu yeniden yazmak zorunda kalmak istemiyorum. Eğer bir erişimci olsaydı, değiştiricinin nasıl çalıştığını değiştirmek zorundayım, bir durum değişkeni ile ya tüm referansları değiştirmem ya da bağlı bir skaler yapmam gerekecek. –

İlgili konular