Role delegation (sort of)

[email protected] (Buddy Burden) Thu, 04 Jul 2013 13:59:30 -0700
Newsgroups perl.moose
Message-ID <[email protected]>
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.