My real code is quite longer/different, so I thought it would be better to post an example here.

My reasons: I found myself typing too much code each time I needed a special configuration class that represents a text config file and has functions to parse, validate (and in reverse also serialize) config entries.

So the idea was to define different config entry types ("file", "ip address", "email address") as traits containing a parser and a serializer function.
In the class representing the config file then I will only have to enrich the attributes with my traits to have a project specific config parser/writer:

has alarmMailsTo => ( traits => ['ConfigEmail'], # trait for type "email" conf_key => 'ALARM_MAILS_TO' # associate with a config key isa => 'ArrayRef[Str]', is => 'rw', );

A problem occurs when a trait needs some runtime information in it's parser/validator method. The problem and the workaround I have found by now is as follows:

Class that represents config file

.. 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' attr_valid_domain => 'validDomain' ## give attr name to trait isa => 'ArrayRef[Str]', is => 'rw', ); ..

Class role

.. role My::Config { method load() { .. ## $attr is a Moose::Meta::Attribute $attr->parse($self, $configString); .. } .. }

Attribute Trait

.. role My::Config::ConfigEmail { has attr_valid_domain => ( isa => 'Str', is => 'rw', required => 1, ); method parse($instance!, $value!) { .. $instance ->meta ->find_attribute_by_name($self->attr_valid_domain) ->get_value($instance); .. } .. }

(Btw. I actually have a "base trait" that contains the parse() method and all "type traits" consume it)

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?

Thanks a lot for your help so far...
-maxhq


In reply to Re^4: Moose: Where to define a method required by an attribute trait? by maxhq
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.