Moose::...deReuse(3)
π Moose::Cookbook::Roles::Comparable_CodeReuse π
okay bestie, welcome to Moose::...deReuse(3) β yes that's the manual page name, it's giving β¨abbreviatedβ¨, don't worry about it. it's from the User Contributed Perl Documentation and it's literally all about using roles for code reuse. we're gonna have a TIME. π¦
πΈ NAME πΈ
Moose::Cookbook::Roles::Comparable_CodeReuse β using roles for code reuse π
β VERSION β
version 2.4000 β periodt, that's the one we're on π
β¨ SYNOPSIS β¨
okay so here's the whole vibe, read it like a recipe bestie:
package Eq;
use Moose::Role;
requires 'equal_to';
sub not_equal_to {
my ( $self, $other ) = @_;
not $self->equal_to($other);
}
package Comparable;
use Moose::Role;
with 'Eq';
requires 'compare';
sub equal_to {
my ( $self, $other ) = @_;
$self->compare($other) == 0;
}
sub greater_than {
my ( $self, $other ) = @_;
$self->compare($other) == 1;
}
sub less_than {
my ( $self, $other ) = @_;
$self->compare($other) == -1;
}
sub greater_than_or_equal_to {
my ( $self, $other ) = @_;
$self->greater_than($other) || $self->equal_to($other);
}
sub less_than_or_equal_to {
my ( $self, $other ) = @_;
$self->less_than($other) || $self->equal_to($other);
}
package Printable;
use Moose::Role;
requires 'to_string';
package US::Currency;
use Moose;
with 'Comparable', 'Printable';
has 'amount' => ( is => 'rw', isa => 'Num', default => 0 );
sub compare {
my ( $self, $other ) = @_;
$self->amount <=> $other->amount;
}
sub to_string {
my $self = shift;
sprintf '$%0.2f USD' => $self->amount;
}
π«Ά DESCRIPTION π«Ά
so roles have two primary purposes, bestie: they can be interfaces, and they can be a means of code reuse. this recipe is showing off the second one, with roles that define comparison and display code for objects. lowkey iconic.
let's start with Eq. first thing, note that we've swapped out use Moose for use Moose::Role π
. we also get a shiny new sugar function, requires:
requires 'equal_to';
this is saying: any class that consumes this role must provide an equal_to method. it can do that directly, or by consuming some other role. no cap.
the Eq role defines its not_equal_to method in terms of the required equal_to method. that way we can minimize the methods that consuming classes have to provide. obsessed honestly.
next role up is Comparable, and it builds on Eq. we pull Eq into Comparable using with, which is another new sugar function:
with 'Eq';
the with function takes a list of roles to consume. in our example, the Comparable role provides the equal_to method that Eq requires. but it could opt not to, in which case a class that consumed Comparable would have to provide its own equal_to. in other words: a role can consume another role without providing any required methods. the way that works is so cute fr.
the Comparable role requires a method, compare:
requires 'compare';
and it also provides a bunch of other methods, all of which ultimately rely on compare:
sub equal_to {
my ( $self, $other ) = @_;
$self->compare($other) == 0;
}
sub greater_than {
my ( $self, $other ) = @_;
$self->compare($other) == 1;
}
sub less_than {
my ( $self, $other ) = @_;
$self->compare($other) == -1;
}
sub greater_than_or_equal_to {
my ( $self, $other ) = @_;
$self->greater_than($other) || $self->equal_to($other);
}
sub less_than_or_equal_to {
my ( $self, $other ) = @_;
$self->less_than($other) || $self->equal_to($other);
}
finally (for the roles anyway), we define the Printable role π. this one exists solely to provide an interface. it has no methods, just a list of required methods. in this case, it just requires a to_string method.
an interface role is useful because it defines both a method and a name. we know that any class which does this role has a to_string method, but we can also assume that this method has the semantics we want. presumably, in real code we would define those semantics in the documentation for the Printable role. (1) β yeah that's a footnote, we'll get to it, hold on π
finally finally, we have the US::Currency class, which consumes both the Comparable and Printable roles:
with 'Comparable', 'Printable';
it also defines a regular Moose attribute, amount:
has 'amount' => ( is => 'rw', isa => 'Num', default => 0 );
and at last we see the implementation of the methods required by our roles. we've got a compare method:
sub compare {
my ( $self, $other ) = @_;
$self->amount <=> $other->amount;
}
by consuming the Comparable role and defining this method, we gain the following methods for free: equal_to, greater_than, less_than, greater_than_or_equal_to and less_than_or_equal_to. free stuff?? slay. π₯
then we have our to_string method:
sub to_string {
my $self = shift;
sprintf '$%0.2f USD' => $self->amount;
}
π CONCLUSION π
roles can be very powerful, bestie. they are a great way of encapsulating reusable behavior, as well as communicating (semantic and interface) information about the methods our classes provide. it's giving main character energy for real.
π FOOTNOTES π
- consider two classes,
RunnerandProcess, both of which define arunmethod. if we just require that an object implements arunmethod, we still aren't saying anything about what that method actually does. if we require an object that implements theExecutablerole, we're saying something about semantics. iykyk π
π AUTHORS π
- Stevan Little <stevan@cpan.org>
- Dave Rolsky <autarch@urth.org>
- Jesse Luehrs <doy@cpan.org>
- Shawn M Moore <sartak@cpan.org>
- ΧΧΧΧ Χ§ΧΧ'ΧΧ (Yuval Kogman) <nothingmuch@woobling.org>
- Karen Etheridge <ether@cpan.org>
- Florian Ragwitz <rafl@debian.org>
- Hans Dieter Pearcey <hdp@cpan.org>
- Chris Prather <chris@prather.org>
- Matt S Trout <mstrout@cpan.org>
look at them, an entire squad of legends, we stan π«Ά
π COPYRIGHT AND LICENSE π
this software is copyright (c) 2006 by Infinity Interactive, Inc.
this is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. so go off, remix it, it's literally yours to share π
okay that's the whole page, and as a little send-off: this was perl v5.42.0, dated 2025-07-25, and you just read Moose::...deReuse(3). mwah, go write some roles bestie π
β¨π¦
π¦ where this page comes from
- fedora 43: perl-Moose 2.4000-4.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms