12

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";
}
4

2 に答える 2

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";
}
于 2009-06-29T01:45:54.397 に答える
2

正直なところ、クラス属性についてはそこまで苦労する必要はないと思います。読み取り専用のクラス属性については、定数を返すサブルーチンを使用するだけです。読み取り/書き込み属性の場合、通常はパッケージ内の単純な状態変数でうまくいきます (より複雑なものが必要になるシナリオにはまだ遭遇していません)。

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

5.10 より前の互換性が必要な場合は、レキシカルを含むプライベート ブロックを使用できます。

于 2009-06-29T07:10:41.720 に答える