当 (is => “rwp”) 时更改作者前缀
Changing writer prefix when (is => “rwp”)
如果我想更改写保护属性,即
use Moops;
class foo {
has attr => (is => "rwp");
}
必须使用 _set_attr()
。
是否可以在不使用显式 writer
的情况下将其更改为 _attr()
?
尝试了 use MooseX::::AttributeShortcuts -writer_prefix => 'prefix';
但没有用。
否,您需要自己设置 writer
.
TLDR:无论如何,底部是一个猴子补丁。
Moops docs 说(强调我的):
Moops uses MooseX::MungeHas in your classes so that the has keyword
supports some Moo-specific features, even when you're using Moose or
Mouse. Specifically, it supports is => 'rwp'
, is => 'lazy'
, builder =>
1
, clearer => 1
, predicate => 1
, and trigger => 1
.
现在我们来看看Moo。在文档的 has
部分,它说(强调我的):
rwp
stands for "read-write protected" and generates a reader like ro
,
but also sets writer to _set_${attribute_name}
for attributes that are
designed to be written from inside of the class, but read-only from
outside. This feature comes from MooseX::AttributeShortcuts.
好的,继续MooseX::AttributeShortcuts:
Specifying is => 'rwp' will cause the following options to be set:
is => 'ro'
writer => "_set_$name"
然而,这正是它的灵感来源。它实际上是在 Method::Generate::Accessor1.
中的 Moo 中实现的
} elsif ($is eq 'rwp') {
$spec->{reader} = $name unless exists $spec->{reader};
$spec->{writer} = "_set_${name}" unless exists $spec->{writer};
} elsif ($is ne 'bare') {
更重要的是,这也不是在 Moops 中完成的。事实上,这发生在 Moops 使用的 MooseX::MungeHas 中,但前提是调用者不是 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 并在 [=26] 中添加一些逻辑来更改 in Moo =] 修饰符 generate_method
。这 对 Moops 不起作用 只要不涉及 Moose-stuff。
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.
如果我想更改写保护属性,即
use Moops;
class foo {
has attr => (is => "rwp");
}
必须使用 _set_attr()
。
是否可以在不使用显式 writer
的情况下将其更改为 _attr()
?
尝试了 use MooseX::::AttributeShortcuts -writer_prefix => 'prefix';
但没有用。
否,您需要自己设置 writer
.
TLDR:无论如何,底部是一个猴子补丁。
Moops docs 说(强调我的):
Moops uses MooseX::MungeHas in your classes so that the has keyword supports some Moo-specific features, even when you're using Moose or Mouse. Specifically, it supports
is => 'rwp'
,is => 'lazy'
,builder => 1
,clearer => 1
,predicate => 1
, andtrigger => 1
.
现在我们来看看Moo。在文档的 has
部分,它说(强调我的):
rwp
stands for "read-write protected" and generates a reader likero
, but also sets writer to_set_${attribute_name}
for attributes that are designed to be written from inside of the class, but read-only from outside. This feature comes from MooseX::AttributeShortcuts.
好的,继续MooseX::AttributeShortcuts:
Specifying is => 'rwp' will cause the following options to be set:
is => 'ro' writer => "_set_$name"
然而,这正是它的灵感来源。它实际上是在 Method::Generate::Accessor1.
中的 Moo 中实现的} elsif ($is eq 'rwp') { $spec->{reader} = $name unless exists $spec->{reader}; $spec->{writer} = "_set_${name}" unless exists $spec->{writer}; } elsif ($is ne 'bare') {
更重要的是,这也不是在 Moops 中完成的。事实上,这发生在 Moops 使用的 MooseX::MungeHas 中,但前提是调用者不是 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 并在 [=26] 中添加一些逻辑来更改 in Moo =] 修饰符 generate_method
。这 对 Moops 不起作用 只要不涉及 Moose-stuff。
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.