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

Dear wisest PerlMonks!

I have a problem concerning Moose traits: When defining a class role and requiring some method with requires, the method has to be implemented in the class.

But where/how to implement a method that is required by an attribute trait?

UPDATE: Alternatively, is it possible to use MooseX::Role::Parameterized together with attribute traits?

Example:

use MooseX::Declare; role My::DirOption { requires '_build_rootdir'; has rootdir => ( isa => 'Str', is => 'rw', lazy => 1, builder => '_build_rootdir', ); } # Make meta attribute trait known to Moose under a short name class Moose::Meta::Attribute::Custom::Trait::DirOption { sub register_implementation {'My::DirOption'} } class My::Config { use strict; use warnings; has testdir => ( traits => ['DirOption'], isa => 'Str', is => 'rw', ); ## This is the wrong place for the builder! method _build_rootdir() { return '/home/paulatreides'; } } 1;
This gives:
'My::DirOption' requires the method '_build_rootdir' to be implemented + by 'Class::MOP::Class::__ANON__::SERIAL::9'

Is there anybody who can light my darkness?

Replies are listed 'Best First'.
Re: Moose: Where to define a method required by an attribute trait?
by stvn (Monsignor) on Apr 28, 2010 at 21:01 UTC

    I think perhaps you want something that ends up looking more like this:

    has testdir => ( traits => ['DirOption'], isa => 'Str', is => 'rw', rootdir => '/home/paulatreides', );
    You can read the Moose::Manual entry on attribute traits to see how that is accomplished, it is fairly straightforward and common use of attribute traits (to add more options to has).

    As for your _build_rootdir approach, you could use MooseX::Role::Parameterized for this. In that case it will look more like this instead

    has testdir => ( traits => [ 'DirOption' => { rootdir => '/home/paulatreides' } + ], isa => 'Str', is => 'rw', );
    This is a less common way to use attribute traits, but it too should work.

    -stvn

      Thank you very much for your hint on how to give a parameter to an attribute trait! I did not find an example anywhere in the docs of MooseX::Role::Parameterized.

      Now I see that this also does not solve my problem, I am sorry that I forgot an important fact: The value given to the trait is no constant, so it has to be a kind of lazy builder.

      So more precisely, I need give an instance value to the trait, something like:

      has rootdir => ( isa => 'Str', is => 'rw', ); has testdir => ( traits => ['DirOption'], isa => 'Str', is => 'rw', rootdir => $self->rootDir, );
      Is this possible?

      -maxhq

        I am not sure why you are using attribute traits in the first place? Seems like you could do this with just plain old vanilla Moose. What do attribute traits give you that using cascading lazy builders would not?

        -stvn