【问题标题】:In Moose, how do I create a rw proxy attribute for another rw attribute在 Moose 中,如何为另一个 rw 属性创建 rw 代理属性
【发布时间】:2021-11-26 14:38:45
【问题描述】:

在 Moose 类中,我有一个 rw 属性引用声明列表中的位置。

has 'option_index' => (
  isa => 'Int',
  is => 'rw',
);

my $options = [qw(one two three)];

has 'option' => (
  is => 'rw',
  # ???
  # should take 'one' and set option_index to 0, ...
  # should return $options->[$self->option_index]
);

我想创建一个代理属性,它获取列表的 option_index 处的值并将 option_index 设置为找到参数的位置。

我可以创建一个简单的 sub 来执行此操作,但我想利用 Moose 类型检查的好处,因此将其声明为属性。

这个可以吗?

  • 我不关心实施,只关心 Moose 设置和
  • option_index 必须保留

【问题讨论】:

    标签: perl moose


    【解决方案1】:

    这是一个使用trigger function的示例:

    package Foo;
    use Moose;
    
    has 'option_index' => (
      isa => 'Int',
      is => 'rw',
      default => 0,
    );
    
    my $options = [qw(one two three)];
    
    has 'option' => (
        is => 'rw',
        isa => 'Str',
        trigger => \&_set_option_trigger,
    );
    
    
    sub _set_option_trigger {
        my ( $self, $new_value, $old_value ) = @_;
    
        for my $idx (0..$#$options) {
            if ($options->[$idx] eq $new_value) {
                $self->option_index($idx);
                return;
            }
        }
        die "Unknown option '$new_value'";
    }
    
    no Moose;
    __PACKAGE__->meta->make_immutable;
    
    package main;
    use strict;
    use warnings;
    use feature qw(say);
    
    my $foo = Foo->new();
    $foo->option('three');
    say "Option is: ", $foo->option;
    say "Option index is : ", $foo->option_index;
    $foo->option('four');
    

    输出

    Option is: three
    Option index is : 2
    Unknown option 'four' at ./p.pl line 30.
    

    编辑

    要让option 属性具有由option_index 属性确定的默认值,您可以尝试添加lazydefault 子,如下所示:

    has 'option' => (
        is => 'rw',
        isa => 'Str',
        lazy => 1,
        default => sub { my $self = shift; $options->[$self->option_index] },
        trigger => \&_set_option_trigger,
    );
    

    【讨论】:

    • 感谢 Håkon 的回复。不幸的是,这依赖于要设置的选项。如果只设置了 option_index,则 option 返回 undef。可能,一个可以在 option_index 处有另一个触发器,但它并没有让我觉得它很优雅......
    • @Jan 查看我的更新答案。对你有帮助吗?
    • 当然可以!我想知道它是否是最精简的实现,但肯定比我的现状更好:)
    猜你喜欢
    • 2020-07-19
    • 2014-11-16
    • 2015-05-27
    • 1970-01-01
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多