MooseX::ErsatzMethod - provide a method implementation that isn't as good as the real thing
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'.
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.
Greetable
name
Termite
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.)
AUTOLOAD
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.
ersatz $name => $coderef
Defines an ersatz function.
Your metarole (i.e. $metarole = Greetable->meta) will have the following additional methods:
$metarole = Greetable->meta
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.
Instances of this class represent an ersatz method.
new(%attrs)
Standard Moose constructor.
code
The coderef for the method.
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.
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
Please report any bugs to http://rt.cpan.org/Dist/Display.html?Queue=MooseX-ErsatzMethod.
Moose::Role.
https://speakerdeck.com/u/sartak/p/moose-role-usage-patterns?slide=32.
Toby Inkster <tobyink@cpan.org>.
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.
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.
To install MooseX::ErsatzMethod, copy and paste the appropriate command in to your terminal.
cpanm
cpanm MooseX::ErsatzMethod
CPAN shell
perl -MCPAN -e shell install MooseX::ErsatzMethod
For more information on module installation, please visit the detailed CPAN module installation guide.