0

在我正在编写的 Moose 扩展中,我试图从属性中访问属性值,而不通过访问器,但我似乎无法做到这一点。

我正在尝试编写此代码

{
    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',
    )
}

这样我就可以(从我的测试中)

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

这就是我在扩展中尝试的

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

1 回答 1

0

我的问题似乎有两个方面,我的匿名子例程没有正确完成,我需要将对象的实例传递给匿名子例程。

这似乎在我的 Moose 扩展中工作

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';
};

我认为我可以将实例传递进去,尽管我不完全确定为什么get_value需要这样做。

于 2012-04-13T05:15:16.973 回答