3

クラスの属性として配列を定義し、クラスがインスタンス化されるときにデータを入力したいと考えています。

$self->attribute->set($id, $value)特定のインデックスに要素を設定するためにメソッドを使用できると思いました。少なくともそれは Moose documentationから理解したものです。

でもやってみると

use Data::Dumper qw( Dumper );
use Moose;

has cells => (
    is => 'rw',
    traits  => ['Array'],
    isa     => 'ArrayRef',
    default => sub { [] },
);

my $app = __PACKAGE__->new();
$app->cells->set($_, $_) for 0..3;
print(Dumper($app->cells));

私は得る

Can't call method "set" on unblessed reference

どうすればset仕事をすることができますか?

4

3 に答える 3

6
use Data::Dumper qw( Dumper );
use Moose;

has cells => (
    is => 'rw',
    traits  => ['Array'],
    isa     => 'ArrayRef',
    default => sub { [] },
    handles => {                   # <---
       set_cell => 'set',          # <---
    },                             # <---
);

my $app = __PACKAGE__->new();
$app->set_cell($_, $_) for 0..3;   # <---
print(Dumper($app->cells));

コメントで反対の主張にもかかわらず、それはまたうまくいきBUILDます。

use Data::Dumper qw( Dumper );
use Moose;

has cells => (
    is => 'rw',
    traits  => ['Array'],
    isa     => 'ArrayRef',
    default => sub { [] },
    handles => {
       set_cell => 'set',
    },
);

sub BUILD {
    my ($self) = @_;
    $self->set_cell($_, $_) for 0..3;
}

my $app = __PACKAGE__->new();
print(Dumper($app->cells));
于 2012-12-15T22:34:50.973 に答える
3

@ikegamiの答えは正しいです。これが拡張された説明です。

問題は次の行にあります。

$app->cells->set($_, $_) for 0..3;

より明確にするために、ループを取り除き、展開してみましょう。

my $cells = $app->cells;
$cells->set(0, 0);

$app->cells呼び出しで定義したとおり、単純な配列参照を返しますhas cells。したがって、$cells は単純な、bless されていない配列リファレンスに他なりません。その上でメソッドを呼び出すことはできません。(残念ながら) autoboxに入らない限り、これが Perl の動作です。

提供されるすべてのメソッドは、属性によって返されるものではなく、オブジェクトに対して呼び出されることに注意してください。また、ドキュメントはこの点について明確ではありません。各メソッドには属性の名前が追加されています。あなたは電話しないでcountくださいcount_cells。あなたは電話しないでsetくださいset_cells

$app->set_cells(0, 0);
print $app->count_cells;
于 2012-12-15T23:31:29.003 に答える
3

あなたはそれをしません。はオブジェクトではなく配列参照であるため、setメソッドはありませ。したがって、メソッドはありません。ネイティブ トレイトを属性に適用しても、arrayref はオブジェクトになりません。代わりに、特性によって提供されるメソッドを使用して、その属性が要求に応答できるようにするだけです。$app->cells$app->cellsArrayhandles

祝福されていない配列参照でメソッドを呼び出せるようにしたい場合は、Moose::Autoboxの使用を検討するかもしれませんが、デメテルの法則を考慮に入れると、ネイティブ トレイトを使用すると、ユーザーがデータ メンバーを直接突くことができるようにします。

于 2012-12-16T00:08:59.730 に答える