2012-04-13 38 views
0

Moose拡張機能では、アクセサーを経由せずに属性内の属性値にアクセスしようとしていますが、この権利を得ることはできません。属性内から属性値を取得

私は

my $t0 = Test->new({ attr1 => 'foo' }); 

isa_ok my $attr0 = $t0->meta->get_attribute('attr0'), 'Class::MOP::Attribute'; 
is $attr0->serialized, 'Y', 'remote_name serializes'; 

isa_ok my $attr1 = $t0->meta->get_attribute('attr1'), 'Class::MOP::Attribute'; 
is $attr1->serialized, 'foo', 'remote_name serializes'; # undef 

私は、(私のテストから)行うことができるように、このコード

{ 
    package Test; 
    use Moose; 
    use MooseX::RemoteName; #provides magic 

    has attr0 => (
     isa   => 'Bool', 
     is   => 'ro', 
     default  => sub { 1 }, 
     serializer => sub { 
      my $s = shift; 
      return $s->get_value($s) ? 'Y' : 'N'; 
     }, 
    ); 

    has attr1 => (
     isa => 'Str', 
     is => 'ro', 
    ) 
} 

を書くことができるようにしようとしている。これは、私が拡張子にしようとしているものです

has serializer => (
    isa  => 'CodeRef', 
    is  => 'ro', 
    lazy  => 1, 
    default => sub { 
     return sub { 
      my $arg = shift; 
      return $arg->get_value($arg->associated_class); 
     } 
    }, 
); 

sub serialized { 
    my $self = shift; 

    my $coderef = $self->serializer; 

    return &$coderef($self); 
} 
+0

シリアライザは単にアクセサを呼び出すことができると思います。私が見ることができるシリアライザをアクセサが呼び出すことはありません。 – Schwern

+0

私はこれを持っているだけの問題は、読者の定義を解除する場合があるということです... – xenoterracide

答えて

0

私の問題は、2つの倍、私の無名サブルーチンが正しく行われていなかったように見える、と私はのインスタンスを渡すために必要なオブジェクトを匿名サブルーチンに追加します。

これは、その後、私は、次の(わずかに異なる)を書くことができます私のムース拡張

has serializer => (
    predicate => 'has_serializer', 
    traits => ['Code'], 
    is  => 'ro', 
    default => sub { 
     return sub { 
      my ($self, $instance) = @_; 
      return $self->get_value($instance); 
     } 
    }, 
    handles => { 
     serializing => 'execute_method', 
    }, 
); 

sub serialized { 
    my ($self, $instance) = @_; 

    return $self->serializing($instance); 
} 

で動作しているようだ問題なく、この試験に合格する

package Test; 
use Moose; 
use MooseX::RemoteName; 

has attr0 => (
    isa  => 'Bool', 
    is   => 'ro', 
    lazy  => 1, 
    default => sub { 1 }, 
    serializer => sub { 
     my ($attr, $instance) = @_; 
     return $attr->get_value($instance) ? 'Y' : 'N'; 
    }, 
); 

subtest t0 => sub { 
    my $t = Test->new; 

    is $t->attr0, 1, 'attr0 is 1'; 

    isa_ok my $attr0 = $t->meta->get_attribute('attr0'), 'Class::MOP::Attribute'; 

    is $attr0->serialized($t), 'Y', 'attr0 serializes'; 
    isa_ok $t, 'Test'; 
}; 

私は完全にsurではないが、私はインスタンスを渡すことができると思うなぜget_valueにそれが必要なの?

+0

'get_value()'がインスタンスを必要とするのは、データが保存されている、つまりインスタンス*が存在するからです。それはクラスにバインドされたデータです。また、これは実際にカリーされていません。あなたは匿名のサブを作成しているだけで、カリングにはそれ以上のものが含まれています(私が知る限り、ここでは何もしていない1つ以上の値でクロージャを作成する必要があります)。 – perigrin

+0

ええ、私は$ attr-> get_valueが属性のインスタンスだと思います... – xenoterracide

+1

あなたのオブジェクトインスタンスを混乱させています。 '$ attr'は' Test'のインスタンスではなく、 'Moose :: Meta :: Attribute'のインスタンスです。適切なデータ構造(適切な値を調べることができるように、この場合は 'Test'のインスタンス)が渡される必要があります。 – perigrin

関連する問題