2009-06-29 11 views
12

私はMooseでclass属性が必要です。今すぐ私は言っている:Mooseでクラス属性を作成する最善の方法は何ですか?

#!/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"; 
} 

答えて

8

私はMooseX :: ClassAttributeを見つけましたが、それは醜いです。これは最もクリーンな方法ですか?

#!/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

これは正しい方法です。別のパッケージでClassAttributeが何をしているのかを見てみると、クラスクラスを作成することもできます。 – castaway

+0

'use strict'と' use warnings'は 'use MooseX :: Declare'と重複していません。 ? –

+0

@Robert Pおそらく、私はこれを書いたときにMooseX :: Declareを使い始めたばかりです。 –

2

正に、私はクラス属性のためにそのすべてのトラブルを考える必要はないと思います。読み取り専用クラスの属性については、定数を返すサブを使用しています。読み書き属性については、パッケージ内の単純な状態変数は、通常のトリック(私はまだ、私はより複雑なものを必要なあらゆるシナリオに実行していない。)

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

は、字句の専用ブロックはできません5.10より前の互換性が必要な場合に使用します。

+2

ああ、id_poolは必ずしも読み取り専用ではないので、アクセサーを持つ真のクラス属性が必要です。 IDプールをデータベースに移動する際に、コードを書き直す必要はありません。アクセサーだった場合は、アクセッサがどのように働いていたかを変更する必要があります。状態変数を使用して、すべての参照を変更するか、スカラーにする必要があります。 –

関連する問題