Skip to content

Commit 3e5fc9a

Browse files
committed
support method modifiers for overrided accessors
Signed-off-by: Ji-Hyeon Gim <[email protected]>
1 parent 974c75f commit 3e5fc9a

File tree

3 files changed

+217
-10
lines changed

3 files changed

+217
-10
lines changed

lib/Moose/Manual/Attributes.pod

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -565,16 +565,6 @@ to C<'Bill'>.
565565
We recommend that you exercise caution when changing the type (C<isa>)
566566
of an inherited attribute.
567567

568-
=head2 Attribute Inheritance and Method Modifiers
569-
570-
When an inherited attribute is defined, that creates an entirely new set of
571-
accessors for the attribute (reader, writer, predicate, etc.). This is
572-
necessary because these may be what was changed when inheriting the attribute.
573-
574-
As a consequence, any method modifiers defined on the attribute's accessors in
575-
an ancestor class will effectively be ignored, because the new accessors live
576-
in the child class and do not see the modifiers from the parent class.
577-
578568
=head1 MULTIPLE ATTRIBUTE SHORTCUTS
579569

580570
If you have a number of attributes that differ only by name, you can declare

lib/Moose/Meta/Attribute.pm

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,8 +1011,31 @@ sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
10111011

10121012
sub install_accessors {
10131013
my $self = shift;
1014+
1015+
my @mods;
1016+
1017+
foreach my $method_meta ( @{ $self->associated_methods } ) {
1018+
my $wrapped = $self->associated_class->find_method_by_name($method_meta->name);
1019+
1020+
next if (!defined($wrapped) || !$wrapped->isa('Class::MOP::Method::Wrapped'));
1021+
1022+
push @mods, map {
1023+
my $type = $_;
1024+
map +[ $wrapped->name, $type, $_ ], $wrapped->${\"${type}_modifiers"};
1025+
} ( qw(after before around) );
1026+
}
1027+
10141028
$self->SUPER::install_accessors(@_);
10151029
$self->install_delegation if $self->has_handles;
1030+
1031+
foreach my $mod ( @mods ) {
1032+
my ($name, $type, $modifier) = @{$mod};
1033+
1034+
my $func = "add_${type}_method_modifier";
1035+
1036+
$self->associated_class->$func($name, $modifier);
1037+
}
1038+
10161039
return;
10171040
}
10181041

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#!/usr/bin/perl
2+
3+
use strict;
4+
use warnings;
5+
6+
use Test::More;
7+
8+
{
9+
package Foo;
10+
use Moose;
11+
12+
has 'foo' => (
13+
is => 'ro',
14+
writer => 'set_foo',
15+
predicate => 'has_foo',
16+
);
17+
18+
has 'foo_arounded' => (
19+
is => 'rw',
20+
isa => 'Int',
21+
default => 0,
22+
);
23+
24+
has 'has_foo_arounded' => (
25+
is => 'rw',
26+
isa => 'Int',
27+
default => 0,
28+
);
29+
30+
around 'has_foo' => sub {
31+
my $orig = shift;
32+
my $self = shift;
33+
34+
$self->has_foo_arounded($self->has_foo_arounded + 1);
35+
36+
$self->$orig(@_);
37+
};
38+
39+
around 'set_foo' => sub {
40+
my $orig = shift;
41+
my $self = shift;
42+
43+
$self->foo_arounded($self->foo_arounded + 1);
44+
45+
$self->$orig(@_);
46+
};
47+
}
48+
49+
{
50+
package Bar;
51+
52+
use Moose;
53+
54+
extends 'Foo';
55+
56+
has '+foo' => (
57+
lazy => 0,
58+
);
59+
60+
has 'bar' => (
61+
traits => ['Array'],
62+
is => 'ro',
63+
writer => 'set_bar',
64+
reader => 'get_bar',
65+
default => sub { [] },
66+
handles => {
67+
add_bar => 'push',
68+
}
69+
);
70+
71+
has 'bar_arounded' => (
72+
is => 'rw',
73+
isa => 'Int',
74+
default => 0,
75+
);
76+
77+
around 'has_foo' => sub {
78+
my $orig = shift;
79+
my $self = shift;
80+
81+
$self->has_foo_arounded($self->has_foo_arounded + 1);
82+
83+
$self->$orig(@_);
84+
};
85+
86+
around 'set_foo' => sub
87+
{
88+
my $orig = shift;
89+
my $self = shift;
90+
91+
$self->foo_arounded($self->foo_arounded + 1);
92+
93+
$self->$orig(@_);
94+
};
95+
96+
around 'get_bar' => sub
97+
{
98+
my $orig = shift;
99+
my $self = shift;
100+
101+
$self->bar_arounded($self->bar_arounded + 1);
102+
103+
$self->$orig(@_);
104+
};
105+
106+
around 'add_bar' => sub
107+
{
108+
my $orig = shift;
109+
my $self = shift;
110+
111+
$self->bar_arounded($self->bar_arounded + 1);
112+
113+
$self->$orig(@_);
114+
};
115+
}
116+
117+
{
118+
package Baz;
119+
120+
use Moose;
121+
122+
extends 'Bar';
123+
124+
has '+bar' => (
125+
lazy => 0,
126+
);
127+
128+
around 'has_foo' => sub {
129+
my $orig = shift;
130+
my $self = shift;
131+
132+
$self->has_foo_arounded($self->has_foo_arounded + 1);
133+
134+
$self->$orig(@_);
135+
};
136+
137+
around 'get_bar' => sub
138+
{
139+
my $orig = shift;
140+
my $self = shift;
141+
142+
$self->bar_arounded($self->bar_arounded + 1);
143+
144+
$self->$orig(@_);
145+
};
146+
147+
around 'add_bar' => sub
148+
{
149+
my $orig = shift;
150+
my $self = shift;
151+
152+
$self->bar_arounded($self->bar_arounded + 1);
153+
154+
$self->$orig(@_);
155+
};
156+
}
157+
158+
{
159+
my $foo = Foo->new;
160+
161+
isa_ok($foo, 'Foo');
162+
163+
$foo->has_foo();
164+
$foo->set_foo(1);
165+
166+
is($foo->has_foo_arounded, 1, '... got hte correct value');
167+
is($foo->foo_arounded, 1, '... got hte correct value');
168+
169+
my $bar = Bar->new;
170+
171+
isa_ok($bar, 'Bar');
172+
173+
$foo->has_foo();
174+
$bar->set_foo(1);
175+
$bar->get_bar();
176+
177+
is($foo->has_foo_arounded, 2, '... got hte correct value');
178+
is($bar->foo_arounded, 2, '... got hte correct value');
179+
is($bar->bar_arounded, 1, '... got hte correct value');
180+
181+
my $baz = Baz->new;
182+
183+
isa_ok($baz, 'Baz');
184+
185+
$foo->has_foo();
186+
$baz->set_foo(1);
187+
$baz->get_bar();
188+
189+
is($foo->has_foo_arounded, 3, '... got hte correct value');
190+
is($baz->foo_arounded, 2, '... got hte correct value');
191+
is($baz->bar_arounded, 2, '... got hte correct value');
192+
}
193+
194+
done_testing;

0 commit comments

Comments
 (0)