perl - 如何将取决于另一个属性的属性约束从触发器提升到类型细化?
问题描述
这有效:
use Moops;
class Foo :ro {
use Types::Common::Numeric qw(PositiveOrZeroInt);
has from => required => true, isa => PositiveOrZeroInt;
has to => required => true, isa => PositiveOrZeroInt, trigger => method($to) {
die 'must be from ≤ to' unless $self->from <= $to
};
}
Foo->new(from => 0, to => 1); # ok
Foo->new(from => 1, to => 0); # "must be from ≤ to at …"
我希望能够以某种方式使约束成为类型的一部分。
use Moops;
class Bar :ro {
use Types::Common::Numeric qw(PositiveOrZeroInt);
has from => required => true, isa => PositiveOrZeroInt;
has to => required => true, isa => PositiveOrZeroInt->where(sub {
$self->from <= $_
});
}
Bar->new(from => 0, to => 1);
# Global symbol "$self" requires explicit package name
# (did you forget to declare "my $self"?)
我检查了where
sub只接收一个参数。
解决方案
如果您想在类型检查中执行此操作,您可以将这两个属性组合成一个属性,该属性将是一个包含两个数字的 arrayref。
use Moops;
class Foo :ro {
use Types::Standard qw(Tuple);
use Types::Common::Numeric qw(PositiveOrZeroInt);
has from_and_to => (
required => true,
isa => Tuple->of(PositiveOrZeroInt, PositiveOrZeroInt)->where(sub {
$_->[0] <= $_->[1];
}),
# Provide `from` and `to` methods to fetch values
handles_via => 'Array',
handles => {
'from' => [ get => 0 ],
'to' => [ get => 1 ],
},
);
# Allow `from` and `to` to be separate in the constructor
method BUILDARGS {
my %args = ( @_==1 ? %{$_[0]} : @_ );
$args{from_and_to} ||= [ $args{from}, $args{to} ];
\%args;
}
}
Foo->new(from => 0, to => 1); # ok
Foo->new(from => 1, to => 0); # "must be from ≤ to at …"
不过,我不会在类型检查中这样做。如果属性是只读的,或者它是读写的,我会在BUILD
(不,不是)中执行此操作。BUILDARGS
trigger
推荐阅读
- python - 在 ubuntu 20.04 LTS 上将文本转为语音听起来很奇怪
- reactjs - 无法使用某些参数链接到 SPO 页面上的 Web 部件
- java - 如何从列表中获取值
并将其存储为双 - unit-testing - 在测试中找不到 RadioListTile
- reactjs - CSS 模块在 Jest 和 Enzyme 的测试中没有按预期工作,使用 create-react-app
- email - 如何在显示时知道邮件是否已发送或保存?
- r - 在 R 中基于多列创建列
- c# - IHM 与 CQRS+ES 的 Api 通信
- java - 材料容器变换过渡在背压上不起作用
- javascript - 字符串混淆