It works, but passing an attribute name to the trait and then passing an instance around seems not very elegant to me. Is there any other way to access the class instance from within an attribute trait method?

I would suggest actually that you not pass an attribute name, but instead pass a method name. Then if you put the method name into a common key like 'parameter_callback' instead of the more specific 'attr_valid_domain' you could likely move all the code up into the My::Config role. Here is an (untested) example of what I am talking about:

with My::Config; ## some runtime information, eventually for the trait's method has validDomain => ( isa => 'Str', is => 'rw', ); has alarmMailsTo => ( traits => ['ConfigEmail'], conf_key => 'ALARM_MAILS_TO' parameter_callback => 'validDomain' ## give a method name isa => 'ArrayRef[Str]', is => 'rw', ); .. ## Class role role My::Config { method load() { .. ## $attr is a Moose::Meta::Attribute my $parameter_callback = $attr->parameter_callback; $attr->parse($configString, $self->$parameter_callback()); .. } } ## Base Attribute Trait role My::Config::AttrBase { has parameter_callback => ( isa => 'Str', is => 'rw', required => 1, ); } ## Attribute Trait role My::Config::ConfigEmail with My::Config::AttrBase { method parse($value!, @parameters) { # now this is a more generic API } }
This has a couple benefits:
  1. Your parse API is now more generic and requires less knowledge of the outside world.
  2. You can easily pass multiple parameters using the parameter_callback since it is just a method name. None of the other code will care if that code is an accessor to an attribute or a regular old method.
  3. You now have room to grow with your parameters. If your $boss comes to you tomorrow and says "The configEmail role needs more parameters". you don't have to worry because you can just write a method to wrap "validDomain" and whatever the other parameter is. Then you just change the appropriate code in 'parse' and your done.
Of course, this is Perl so there is always more than one way to do it and there is nothing wrong with your approach really.

-stvn

In reply to Re^5: Moose: Where to define a method required by an attribute trait? by stvn
in thread Moose: Where to define a method required by an attribute trait? by maxhq

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.