在 Moose 中,如何对 arrayref setter 进行 uniq?

In Moose, how do I uniq an arrayref setter?

我有一只驼鹿 class

has 'unique_ints' => (
    is              => 'rw',
    isa             => 'ArrayRef[Int]',
    default         => sub { [] },
);

保证 unique_int 唯一性的最佳方法是什么?

Moose 属性可以有一个 trigger 属性 ,每当该属性发生更改时都会调用它。 属性 是对传递对象的方法的引用以及属性的新旧版本。所以我们可以这样写:

package UniqInt;

use Moose;

use List::Util 'uniqint';

has 'unique_ints' => (
    is              => 'rw',
    isa             => 'ArrayRef[Int]',
    default         => sub { [] },
    trigger         => \&_ensure_uniq,
);

sub _ensure_uniq {
  my $self = shift;
  my ($new) = @_;

  $self->{unique_ints} = [ uniqint @$new ];
}

1;

请注意,在触发器方法中,我们使用直接散列访问属性值,因为再次调用增变器会再次调用触发器方法并使我们陷入无限的递归陷阱。

我们可以这样测试方法:

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

use UniqInt;

my $obj = UniqInt->new;

$obj->unique_ints([1 .. 5]);

say join ',', @{$obj->unique_ints};

$obj->unique_ints([1 .. 5, 1 .. 5]);

say join ',', @{$obj->unique_ints};

正如预期的那样,产生了这个输出:

1,2,3,4,5
1,2,3,4,5

更新: 另请注意,由于我没有使用触发方法的第三个参数(这是属性的先前值),因此我将忽略它。