Skip Menu |

This queue is for tickets about the Class-MOP CPAN distribution.

Report information
The Basics
Id: 41449
Status: resolved
Priority: 0/
Queue: Class-MOP

People
Owner: Nobody in particular
Requestors:
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: accessor installation overwrites pre-existing subs
Here's a rough patch that fixes this issue and a test that illustrates it. Unfortunately the patch causes some other tests to fail. <patch> --- lib/Class/MOP/Attribute.pm (revision 6867) +++ lib/Class/MOP/Attribute.pm (working copy) @@ -367,23 +367,23 @@ $class->add_method( $self->process_accessors('accessor' => $self->accessor(), $inline) - ) if $self->has_accessor(); + ) if $self->has_accessor() && ! $class->has_method( $self->accessor ); $class->add_method( $self->process_accessors('reader' => $self->reader(), $inline) - ) if $self->has_reader(); + ) if $self->has_reader() && ! $class->has_method( $self->reader ); $class->add_method( $self->process_accessors('writer' => $self->writer(), $inline) - ) if $self->has_writer(); + ) if $self->has_writer() && ! $class->has_method( $self->writer ); $class->add_method( $self->process_accessors('predicate' => $self->predicate(), $inline) - ) if $self->has_predicate(); + ) if $self->has_predicate() && ! $class->has_method( $self->predicate ); $class->add_method( $self->process_accessors('clearer' => $self->clearer(), $inline) - ) if $self->has_clearer(); + ) if $self->has_clearer() && ! $class->has_method( $self->clearer ); return; } </patch> <test> #!/usr/bin/perl use Class::MOP; use strict; use Test::More tests => 5; use warnings; { package Foo; use strict; use warnings; use metaclass; __PACKAGE__->meta->add_attribute( 'foo' => ( accessor => 'foo_accessor', reader => 'foo_reader', writer => 'foo_writer', predicate => 'foo_predicate', clearer => 'foo_clearer', ) ); sub foo_accessor { "Don't tread on me! (a)" } sub foo_reader { "Don't tread on me! (r)" } sub foo_writer { "Don't tread on me! (w)" } sub foo_predicate { "Don't tread on me! (p)" } sub foo_clearer { "Don't tread on me! (c)" } } { Foo->meta->make_immutable( inline_constructor => 1, inline_accessors => 1, ); my $foo = Foo->new; is( $foo->foo_accessor, "Don't tread on me! (a)", 'pre-existing foo_accessor sub persists' ); is( $foo->foo_reader, "Don't tread on me! (r)", 'pre-existing foo_reader sub persists' ); is( $foo->foo_writer, "Don't tread on me! (w)", 'pre-existing foo_writer sub persists' ); is( $foo->foo_predicate, "Don't tread on me! (p)", 'pre-existing foo_predicate sub persists' ); is( $foo->foo_clearer, "Don't tread on me! (c)", 'pre-existing foo_clearer sub persists' ); } </test>
This is now a warning at the Moose level. Doing it in CMOP is irritating because bootstrapping involves redefining every interesting method in CMOP. We also aren't ready to really change behavior yet, so it's a warning and not a silent lack of replacement.