不,您需要自己通过设置writer
.
TLDR:无论如何,底部是一个猴子补丁。
Moops文档说(强调我的):
Moops 在您的类中使用 MooseX::MungeHas,因此 has 关键字支持一些Moo 特定的功能,即使您使用的是 Moose 或 Mouse。具体来说,它支持is => 'rwp'
, is => 'lazy'
, builder =>
1
, clearer => 1
, predicate => 1
, 和trigger => 1
.
现在让我们去看看Moo。在has
文档的部分中,它说(强调我的):
rwp
代表“读写保护”并生成类似的读取器ro
,但还将 writer 设置为_set_${attribute_name}
用于从类内部写入但从外部只读的属性。此功能来自 MooseX::AttributeShortcuts。
好的,继续MooseX::AttributeShortcuts:
指定 is => 'rwp' 将导致设置以下选项:
is => 'ro'
writer => "_set_$name"
然而,这正是它受到启发的地方。它实际上是在 Moo 中的Method::Generate::Accessor 1中实现的。
} elsif ($is eq 'rwp') {
$spec->{reader} = $name unless exists $spec->{reader};
$spec->{writer} = "_set_${name}" unless exists $spec->{writer};
} elsif ($is ne 'bare') {
更重要的是,这也不是在 Moops 中完成的。事实上,这发生在MooseX::MungeHas中,Moops 使用它,但前提是调用者不是 Moo:
push @code, ' if ($_{is} eq q(rwp)) {';
push @code, ' $_{is} = "ro";';
push @code, ' $_{writer} = "_set_$_" unless exists($_{writer});';
push @code, ' }';
看起来很清楚。它在生成的代码中。如果仅使用 Moo,以下解决方案可能会起作用,但我不知道如何强制。
您确实可以通过使用 Class::Method::Modifiers 连接到 Moo 的 Method::Generate::Accessor 并在修饰符中添加一些逻辑来更改Moo中的. 只要没有涉及驼鹿的东西,这对 Moops不起作用。around
generate_method
use Moops;
BEGIN {
require Method::Generate::Accessor; # so it's in %INC;
require Class::Method::Modifiers;
Class::Method::Modifiers::around( 'Method::Generate::Accessor::generate_method' => sub {
my $orig = shift;
# 0 1 2 3 4
# my ($self, $into, $name, $spec, $quote_opts) = @_;
if ($_[3]->{is} eq 'rwp') {
$_[3]->{writer} = "_explicitly_set_$_[2]" unless exists $_[3]->{reader};
}
$orig->(@_);
});
}
class Foo {
has attr => ( is => "rwp" );
}
use Data::Printer;
my $foo = Foo->new( attr => 1 );
p $foo;
输出:
Foo {
Parents Moo::Object
public methods (2) : attr, new
private methods (1) : _explicitly_set_attr
internals: {
attr 1
}
}
1)我发现使用grep.cpan.me。