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 >