NAME
MooseX::ErsatzMethod - provide a method implementation that isn't as good as the real thing
SYNOPSIS
package Greetable;
use Moose::Role;
use MooseX::ErsatzMethod;
sub greet {
my $self = shift;
say "Hello ", $self->name;
}
ersatz name => sub {
my $self = shift;
return Scalar::Util::refaddr($self);
};
package Person;
use Moose;
with 'Greetable';
has name => (is => 'ro', isa => 'Str');
package Termite;
use Moose;
with 'Greetable';
# no need to implement 'name'.
DESCRIPTION
MooseX::ErsatzMethod provides a mechanism for Moose roles to provide fallback implementations of methods that they really want for consuming classes to implement. In the SYNOPSIS section, the Greetable
role really wants consuming classes to implement a name
method. The Termite
class doesn't implement name
, but it's OK, because Greetable
provides a fallback (albeit rubbish) implementation of the method.
But wait! I hear you say. Don't roles already work that way? Can't a role provide an implementation of a method which consuming classes can override? Yes, they can. However, the precedence is:
consuming class's implementation (wins)
role's implementation
inherited implementation (e.g. from parent class)
That is, the role's method implementation overrides methods inherited from the parent class. An ersatz method implementation sits right at the bottom of the heirarchy; it is only used if the consuming class and its ancestors cannot provide the method. (It still beats AUTOLOAD
though.)
One other feature of ersatz methods is that they can never introduce role composition conflicts. If you compose two different roles which both provide ersatz method implementations, an arbitrary method implementation is selected.
Functions
Metarole Trait
Your metarole (i.e. $metarole = Greetable->meta
) will have the following additional methods:
ersatz_methods
-
Returns a name => object hashref of ersatz methods for this class. The objects are instances of MooseX::ErsatzMethod::Meta::Method.
all_ersatz_methods
-
Returns just the values (objects) from the
ersatz_methods
hash. add_ersatz_method($name, $coderef)
-
Given a name and coderef, creates a MooseX::ErsatzMethod::Meta::Method object and adds it to the
ersatz_methods
hash. apply_all_ersatz_methods_to_class($class)
-
Given a Moose::Meta::Class object, iterates through
all_ersatz_methods
applying each to the class. This procedure skips any ersatz method for which this role can provide a real method.
MooseX::ErsatzMethod::Meta::Method
Instances of this class represent an ersatz method.
new(%attrs)
-
Standard Moose constructor.
code
-
The coderef for the method.
name
-
The sub name for the method (not including the package).
associated_role
-
The metarole associated with this method (if any).
apply_to_class($class)
-
Given a Moose::Meta::Class object, installs this method into the class unless the class (or a superclass) already has a method of that name.
CAVEATS
If you use one-at-a-time role composition, then ersatz methods in one role might end up "beating" a proper method provided by another role.
with 'Role1'; with 'Role2'; # No!
with qw( Role1 Role2 ); # Yes
BUGS
Please report any bugs to http://rt.cpan.org/Dist/Display.html?Queue=MooseX-ErsatzMethod.
SEE ALSO
https://speakerdeck.com/u/sartak/p/moose-role-usage-patterns?slide=32.
AUTHOR
Toby Inkster <tobyink@cpan.org>.
COPYRIGHT AND LICENCE
This software is copyright (c) 2012, 2014 by Toby Inkster.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
DISCLAIMER OF WARRANTIES
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.