No, you need to do that yourself by setting the writer
.
TLDR: At the bottom is a monkey-patch to do it anyway.
The Moops docs say (emphasys mine):
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
.
Now let's go look at Moo. In the has
section of the doc, it says (emphasys mine):
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.
Ok, on to MooseX::AttributeShortcuts:
Specifying is => 'rwp' will cause the following options to be set:
is => 'ro'
writer => "_set_$name"
However, this is just where it was inspired. It is actually implemented in Moo in Method::Generate::Accessor1.
} elsif ($is eq 'rwp') {
$spec->{reader} = $name unless exists $spec->{reader};
$spec->{writer} = "_set_${name}" unless exists $spec->{writer};
} elsif ($is ne 'bare') {
And even more actually, that is also not where it is done in Moops. In fact, that happens in MooseX::MungeHas, which Moops uses, but only if the caller is not Moo:
push @code, ' if ($_{is} eq q(rwp)) {';
push @code, ' $_{is} = "ro";';
push @code, ' $_{writer} = "_set_$_" unless exists($_{writer});';
push @code, ' }';
Looks pretty clear. It's in generated code. The below solution might work if it uses only Moo, but I don't know how to force that.
You are indeed able to change that in Moo by hooking into Moo's Method::Generate::Accessor using Class::Method::Modifiers and adding a bit of logic in an around
modifier to generate_method
. This does not work works for Moops as long as there is no Moose-stuff involved.
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;
Output:
Foo {
Parents Moo::Object
public methods (2) : attr, new
private methods (1) : _explicitly_set_attr
internals: {
attr 1
}
}
1) I found that using grep.cpan.me.