The easiest way to jump start a discussion is to present a bad answer,
then let everyone squawk in protest with better answers.

Create your role Persistent which requires a number of the methods
from MooseX::Storage and supplies the API that you want.  If $storage
is something that does MooseX::Storage, you can then turn it into a
Persistent thing with:

Persistent->meta->apply($storage);

If you have another possible $storage thing, you might need to apply
an adaptor role first to give it the methods that you want.

Persistent::SomeAdaptor->meta->apply($storage);
Persistent->meta->apply($storage);

And now anything that you require to be Persistent can be assumed to
always satisfy your interface, no matter how it is implemented under
the hood (which might or might not be a MooseX::Storage type thing).

Expecting better informed squawking in 3...2...1...

On Thu, Jul 4, 2013 at 1:59 PM, Buddy Burden <barefootco...@gmail.com> wrote:
> Guys,
>
> Okay, so if I want to create a class which fulfills the interface of another
> class, I would use inheritance.  But if I want to create a class which
> specifically does _not_ fulfill the interface of another class--let's say I
> want to create a [facade
> pattern|http://en.wikipedia.org/wiki/Facade_pattern]--then I use delegation
> instead.  So far so good.
>
> But what aobut the same choice for roles?  Let's say I want to create an
> interface for something--let's say storing and loading an object.  Well, one
> choice is to use MooseX::Storage.  That's nice and simple, and (extra added
> bonus) already built for me.  But let's say that I have plans to move to a
> more complex back-end storage system one day (perhaps I'll want to store to
> a DB instead, or something along those lines).  It would behoove me,
> methinks, to hedge my bets by creating a simple API layer between my code
> and MooseX::Storage.  This will make it much simpler to swap out back-ends
> later.
>
> This is a very common thing with classes, and I've done it many many times.
> But I've never tried it with roles.
>
> Now, if I compose the base role (in this case, MooseX::Storage) into my role
> (let's call it Persistent), then any classes which compose Persistent will
> also get the methods from MooseX::Storage.  That's like inheritance, and
> that's not what I want.  What I want is more like delegation, but obviously
> I can't quite do that: my Persistent role could have an attribute, sure, but
> it can't be an attribute of type MooseX::Storage, because you can't
> instantiate a role.
>
> So my first thought is just to use `excludes` to "block" the MooseX::Storage
> methods from being composed into my classes.  But then I remembered [this
> discussion|http://www.nntp.perl.org/group/perl.moose/2013/03/msg2590.html]
> which seemed to end with the conclusion that one _might_ need `alias`
> (_maybe_), but one should _never_ need `excludes` unless one is doing
> something wrong.(*)
>
> So that tells me that there's probably a Better Way(tm) that I just don't
> know about, due to my inexperience with roles.  So I humbly request the
> greater wisdom of the Moosite community.  Please, show me the way. :-)
>
>
>                 -- Buddy
>
>
> (*) Admittedly, not everyone agreed (particularly Ovid).  But that seemed
> the majority opinion.

Reply via email to