monktopher has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks, I'm working my way through learning Moose and have been finding it difficult to get method delegation working correctly. I've gone through the Moose Delegation documentation, but haven't found anything that relates to the issue I'm having. I have three different classes:

Author.pm
#!/usr/bin/perl package Author; use Moose; has 'name' => ( is => 'rw', writer => 'set_name', reader => 'get_name', ); has 'email', is => 'rw'; sub set_name { my ($self, $name) = @_; $self->name = $name; } sub get_name { my $self = shift; return $self->name; } 1

Post.pm
#!/usr/bin/perl package Post; use Moose; use Author; #Define object attributes: has 'title', is => 'rw', isa => 'Str'; has 'date', is => 'rw', isa => 'Str'; has 'text', is => 'rw', isa => 'Str'; has 'autho r' => ( is => 'rw', isa => 'Author', handles => [ qw ' get_name set_name ' ], ); 1

post-test.pl
#!/usr/bin/perl use Post; use Moose; my $post = Post->new(); $post->title("First post!"); $post->date("Today"); $post->text("Text within the first post. Hello Hello Hello."); $post->set_name("Monk");

When I try and run post-test.pl, I get the following error:

You are overwriting a locally defined method (get_name) with an access +or at /usr/local/lib/perl/5.10.1/Moose/Meta/Attribute.pm line 1053 Moose::Meta::Attribute::_process_accessors('Moose::Meta::Attribute +=HASH(0x1828380)', 'reader', 'get_name', undef) called at /usr/local/ +lib/perl/5.10.1/Class/MOP/Attribute.pm line 428 Class::MOP::Attribute::install_accessors('Moose::Meta::Attribute=H +ASH(0x1828380)') called at /usr/local/lib/perl/5.10.1/Moose/Meta/Attr +ibute.pm line 1013 Moose::Meta::Attribute::install_accessors('Moose::Meta::Attribute= +HASH(0x1828380)') called at /usr/local/lib/perl/5.10.1/Class/MOP/Clas +s.pm line 891 Class::MOP::Class::__ANON__() called at /usr/local/share/perl/5.10 +.1/Try/Tiny.pm line 76 eval {...} called at /usr/local/share/perl/5.10.1/Try/Tiny.pm line + 67 Try::Tiny::try('CODE(0x1820948)', 'Try::Tiny::Catch=REF(0x18187e8) +') called at /usr/local/lib/perl/5.10.1/Class/MOP/Class.pm line 896 Class::MOP::Class::_post_add_attribute('Moose::Meta::Class=HASH(0x +1819178)', 'Moose::Meta::Attribute=HASH(0x1828380)') called at /usr/l +ocal/lib/perl/5.10.1/Class/MOP/Mixin/HasAttributes.pm line 44 Class::MOP::Mixin::HasAttributes::add_attribute('Moose::Meta::Clas +s=HASH(0x1819178)', 'Moose::Meta::Attribute=HASH(0x1828380)') called +at /usr/local/lib/perl/5.10.1/Moose/Meta/Class.pm line 570 Moose::Meta::Class::add_attribute('Moose::Meta::Class=HASH(0x18191 +78)', 'name', 'reader', 'get_name', 'writer', 'set_name', 'definition +_context', 'HASH(0x11d2a60)', 'is', ...) called at /usr/local/lib/per +l/5.10.1/Moose.pm line 79 Moose::has('Moose::Meta::Class=HASH(0x1819178)', 'name', 'is', 'rw +', 'writer', 'set_name', 'reader', 'get_name') called at /usr/local/l +ib/perl/5.10.1/Moose/Exporter.pm line 370 Moose::has('name', 'is', 'rw', 'writer', 'set_name', 'reader', 'ge +t_name') called at Author.pm line 9 require Author.pm called at Post.pm line 6 Post::BEGIN() called at Author.pm line 0 eval {...} called at Author.pm line 0 require Post.pm called at post-test.pl line 3 main::BEGIN() called at Author.pm line 0 eval {...} called at Author.pm line 0 You are overwriting a locally defined method (set_name) with an access +or at /usr/local/lib/perl/5.10.1/Moose/Meta/Attribute.pm line 1053 Moose::Meta::Attribute::_process_accessors('Moose::Meta::Attribute +=HASH(0x1828380)', 'writer', 'set_name', undef) called at /usr/local/ +lib/perl/5.10.1/Class/MOP/Attribute.pm line 432 Class::MOP::Attribute::install_accessors('Moose::Meta::Attribute=H +ASH(0x1828380)') called at /usr/local/lib/perl/5.10.1/Moose/Meta/Attr +ibute.pm line 1013 Moose::Meta::Attribute::install_accessors('Moose::Meta::Attribute= +HASH(0x1828380)') called at /usr/local/lib/perl/5.10.1/Class/MOP/Clas +s.pm line 891 Class::MOP::Class::__ANON__() called at /usr/local/share/perl/5.10 +.1/Try/Tiny.pm line 76 eval {...} called at /usr/local/share/perl/5.10.1/Try/Tiny.pm line + 67 Try::Tiny::try('CODE(0x1820948)', 'Try::Tiny::Catch=REF(0x18187e8) +') called at /usr/local/lib/perl/5.10.1/Class/MOP/Class.pm line 896 Class::MOP::Class::_post_add_attribute('Moose::Meta::Class=HASH(0x +1819178)', 'Moose::Meta::Attribute=HASH(0x1828380)') called at /usr/l +ocal/lib/perl/5.10.1/Class/MOP/Mixin/HasAttributes.pm line 44 Class::MOP::Mixin::HasAttributes::add_attribute('Moose::Meta::Clas +s=HASH(0x1819178)', 'Moose::Meta::Attribute=HASH(0x1828380)') called +at /usr/local/lib/perl/5.10.1/Moose/Meta/Class.pm line 570 Moose::Meta::Class::add_attribute('Moose::Meta::Class=HASH(0x18191 +78)', 'name', 'reader', 'get_name', 'writer', 'set_name', 'definition +_context', 'HASH(0x11d2a60)', 'is', ...) called at /usr/local/lib/per +l/5.10.1/Moose.pm line 79 Moose::has('Moose::Meta::Class=HASH(0x1819178)', 'name', 'is', 'rw +', 'writer', 'set_name', 'reader', 'get_name') called at /usr/local/l +ib/perl/5.10.1/Moose/Exporter.pm line 370 Moose::has('name', 'is', 'rw', 'writer', 'set_name', 'reader', 'ge +t_name') called at Author.pm line 9 require Author.pm called at Post.pm line 6 Post::BEGIN() called at Author.pm line 0 eval {...} called at Author.pm line 0 require Post.pm called at post-test.pl line 3 main::BEGIN() called at Author.pm line 0 eval {...} called at Author.pm line 0 Cannot delegate set_name to set_name because the value of author is no +t defined at /usr/local/lib/perl/5.10.1/Moose/Meta/Method/Delegation. +pm line 99 Post::set_name('Post=HASH(0x1848938)', 'Monk') called at post-test +.pl line 12 ------------------ (program exited with code: 255) Press return to continue

All 3 of the files listed above are in the same directory if that's helpful. Any ideas?
Thanks, Monktopher

Replies are listed 'Best First'.
Re: Moose delegate methods, value not defined
by chromatic (Archbishop) on Mar 05, 2012 at 05:10 UTC

    The first error means that these are redundant:

    has 'name' => ( is => 'rw', writer => 'set_name', reader => 'get_name', ); has 'email', is => 'rw'; sub set_name { my ($self, $name) = @_; $self->name = $name; } sub get_name { my $self = shift; return $self->name; }

    Moose happily generates those methods for you. Let it.

    That leaves:

    Cannot delegate set_name to set_name because the value of author is not defined...

    ... which means that when you create your Post object and call $post->set_name( ... ), if $post contains no author, you get an error message to that effect. Pass in an author or create one (with a builder perhaps).


    Improve your skills with Modern Perl: the free book.

      Thanks for the reply. From the documentation, I was under the impression that

      has 'author' => ( is => 'ro', isa => 'Author', handles => [qw( name )], );

      would create an Author object (using the isa command) in the background. I guess I'm incorrect in thinking this.

      I had tried letting Moose generate the accessory methods, but wasn't sure if handles was looking for an explicitly defined method in the module or not.

      Again, thanks for the reply.

        isa imposes a constraint on what can be placed in author. It doesn't place anything in author. Perhaps you want to add

        default => sub { Author->new() },