Subject: | Warn or confess about overriding a local method with an accessor |
Hi gang,
When I was giving the Moose course, this came up somehow:
package Point;
use Moose;
has x => (is => 'ro');
sub x { }
The "x" accessor silently redefined Point->x which kind of sucks. We
should have the same error as we do in Moose for delegate methods
overriding a local method.
I have a Class-MOP patch (attached) for this, and we have todo tests in
Moose. Unfortunately, the Class-MOP bootstrap process does this all over
the place. I'm not sure how to fix this, other than something idiotic
like this in all of the primary Class-MOP packages:
sub is_bootstrapper { (blessed(shift) || shift) eq __PACKAGE__ }
Ideas?
Shawn
Subject: | accessor-override.diff |
diff --git a/lib/Class/MOP/Attribute.pm b/lib/Class/MOP/Attribute.pm
index 9c9f3f7..eef23d1 100644
--- a/lib/Class/MOP/Attribute.pm
+++ b/lib/Class/MOP/Attribute.pm
@@ -356,6 +356,11 @@ sub _process_accessors {
(ref($accessor) eq 'HASH')
|| confess "bad accessor/reader/writer/predicate/clearer format, must be a HASH ref";
my ($name, $method) = %{$accessor};
+
+ if ($self->associated_class->has_method($name)) {
+ confess "You cannot overwrite a locally defined method ($name) with an accessor";
+ }
+
$method = $self->accessor_metaclass->wrap(
$method,
package_name => $self->associated_class->name,
@@ -366,6 +371,10 @@ sub _process_accessors {
return ($name, $method);
}
else {
+ if ($self->associated_class->has_method($accessor)) {
+ confess "You cannot overwrite a locally defined method ($accessor) with an accessor";
+ }
+
my $inline_me = ($generate_as_inline_methods && $self->associated_class->instance_metaclass->is_inlinable);
my $method;
eval {