Hi All,

Shawn Moore and I have been having a conversation about
MooseX::Role::Parameterized, a brilliant concept and excellent module.  It
provides a solution to a feature that Moose core seemingly lacks.  ( I could
be mistaken here, though ).   This is the use of *prototype* roles and by
extension attributes, types etc.  My focus is on attributes.

I find myself using the same attributes over and over.  For example, I often
have a file attribute.  Or a date attribute using DateTime.  Moose lets me
do this, but:

   - I am loathe to continually write attributes for each class :
      - I want to store these in roles
      - I want to have them parameterized.  For example, sometimes the name
      for a file attribute is 'file', sometimes 'infile', sometimes 'tmp'.
      - I want them them in a central location where I can develop test for
   them.


Syntactically, my goal is to be able to code something like:

use Moose;
    with 'MooseX::Attribute::Parameterized' => ( library =>
'/path/to/prototypes' );

has 'tmpfile' => ( required => 1, prototype => 'file' );


The prototype argument ( implemented as metaclass trait?)  would indicate
that the file role would be added to this class.  The role would load all
the associated behavior necessary to support this attribute including types,
etc.  These would be specified in the 'file' role.

The goal for the developer of the 'file' role would be to make this as close
to Moose as possible.  The developer would write a normal Moose role:

               package Path::To::Prototypes::File;
use Moose::Role;

has 'file' => ( ... );


When the class is constructed, the Role would be consumed, but applying the
customizations rather than the straight role.  Thus prototypes.  In the
example, the attribute name is 'tmpfile' not 'file' and the attribute is now
required.

Shawn's and MooseX::Role::Parameterized gives a valid solution.   But it
requires a little more complexity than needed.  He suggests:

use Moose;
with 'AttributeProvider::File' => { name => 'tmpfile', options => {required
=> 1 } };
with 'AttributeProvider::Date' => { name => 'date' };

package AttributeProvider::File;
use MooseX::Role::Parameterized;

parameter name => (
   is => 'rw',
   isa => 'Str',
);

# it would be nice to have some way of asking for "everything else passed in
the hashref"
parameter options => (
   is => 'rw',
   isa => 'HashRef',
   auto_deref => 1,
);

role {
   my $p = shift;
   has $p->name => (
       isa => 'Path::Class::File', # or whatever your defaults are for this
role
       $p->options,
   );
};


So my questions are:

_1_  Might there be an easier, Moose way for building/using prototypes.  I
like MooseX::Role::Parameterized, but it might be overkill.

_2_. Is there a prototype concept in the Moose roadmap?  If I had to
presume, I would guess yes, since the Moose folks seem to think of
everything.

_3_ Do you think that the Moose community would benefit from a well designed
and well tested set of attributes, types, etc.  that can be used and
customized off the shelf.  I think the benefits are twofold:
1) The reduced need for attribute, type specifications
2) An easier mechanism for CPAN authors to Moose-ify there modules

Thanks in Advance,

Chris






Forwarded message ----------
From: Christopher Brown <cbr...@opendatagroup.com>
Date: Sat, Dec 13, 2008 at 2:00 PM
Subject: Re: MooseX::Role::Parameterized
To: Sartak <sar...@gmail.com>


Shawn,

Parameterized roles are brilliant.  Here is my idea for using them (
Feedback appreciated. )

 I find myself using the same attributes over and over.  For example, I give
a option that evaluates to a filename.  Or I want a date attribute using
DateTime.  Moose lets me do this, but:

   - I am loathe to continually write attributes for each class :
      - Store these in roles
      - Have them parameterized ... sometimes the name for a file attribute
      is file, sometimes infile, sometimes tmp
      - Have them in a central location and tests for them

What I really want to do is:

has tmpfile => ( required => 1, prototype => 'file' );

And that it will load the 'file' role which provides a attribute name
tmpfile and set required => 1 and loads all the associated behavior, types,
etc.  with that attribute as a role.

I think that MooseX::Parameterized::Roles gives me most of this.  No.  But
what I really want is:

For the end user the goal is to make using standard attributes easy.  For
the most part this is all I would want them to have to do:



  has tmpfile => ( prototype => 'file' );
  has date     => ( prototype => 'date' );

....

For the developer, I would like them to simply write Roles as they normally
would:

package MoosX::Attribute::Parameterized;
use Moose::Role;

has file => ( .... );


I figure you must've had some thoughts about this in the design of MXRP.
No?  You must've thought hard about overloading 'has', etc.  and figured it
was the best way to get parameterized roles ... no?

I would appreciate your thoughts,

Chris






On Thu, Dec 11, 2008 at 3:37 PM, Sartak <sar...@gmail.com> wrote:

> On Thu, Dec 11, 2008 at 6:07 PM, Christopher Brown
> <cbr...@opendatagroup.com> wrote:
> > Shawn,
>
> Hey Chris,
>
> > Congratulations.  This is an excellent bit of code.  I love it.  It
> solves a
> > very oft encountered problem.  You (we?) should advocate moving it into
> > Moose core.
> >
> > Keep up the excellent work,
>
> Wow, thank you for your kind words! You just made my day. :)
>
> I'm not sure about pushing MXRP into core Moose. The role {} trick in
> particular annoys some people. Also the code is very new and still has
> some rough edges that need to be thought out (in particular, what do
> to about "alias" and "excludes").
>
> There are a few possible implementations for parameterized roles. I
> just went with what I knew I could actually implement. I'll give it a
> while for other people to try out MXRP and any other implementations
> that pop up, so we can see what works best, and which implementation
> should be cored.
>
> I'm very glad my goal of complete parameterization has been met. I'm
> not sure if any other implementations will be able to offer that.
>
> > Chris
>
> Shawn
>

Reply via email to