++ed by:
148 non-PAUSE users
Dave Rolsky
and 1 contributors

# NAME

Moose::Cookbook::Roles::Recipe1 - The Moose::Role example

# SYNOPSIS

``````  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

Roles have two primary purposes: as interfaces, and as a means of code reuse. This recipe demonstrates the latter, with roles that define comparison and display code for objects.

Let's start with `Eq`. First, note that we've replaced `use Moose` with `use Moose::Role`. We also have a new sugar function, `requires`:

``  requires 'equal_to';``

This says that any class which consumes this role must provide an `equal_to` method. It can provide this method directly, or by consuming some other role.

The `Eq` role defines its `not_equal_to` method in terms of the required `equal_to` method. This lets us minimize the methods that consuming classes must provide.

The next role, `Comparable`, builds on the `Eq` role. We include `Eq` in `Comparable` using `with`, 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 required by `Eq`. However, 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 `Comparable` role requires a method, `compare`:

``  requires 'compare';``

The `Comparable` role also provides a number 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, we define the `Printable` role. This role 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)

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 );``

Finally we see the implementation of the methods required by our roles. We have 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`.

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. They are a great way of encapsulating reusable behavior, as well as communicating (semantic and interface) information about the methods our classes provide.

# FOOTNOTES

(1)

Consider two classes, `Runner` and `Process`, both of which define a `run` method. If we just require that an object implements a `run` method, we still aren't saying anything about what that method actually does. If we require an object that implements the `Executable` role, we're saying something about semantics.

# AUTHORS

Stevan Little <stevan@iinteractive.com>

Dave Rolsky <autarch@urth.org>