Moose

Method Modifiers

Method modifiers are one of the more powerful and flexible features of Moose. The most common types of modifiers are before, after and around. Before and after are really just "hooks" to execute some code whenever a given method is called, either before or after, as the names imply. For example, this would print a string every time fire_all is called:


before 'fire_all' => sub {
        my $self = shift;
        print "Say hello to my little friend!\n";
};

The "around" modifier is quite a bit more powerful than before and after because it actually can change the arguments passed to, and the data returned from, the original method. It also can programmatically decide whether even to call the original method at all.

Around modifiers actually replace the original method, but get passed the original method and arguments to be able to call it within the new modifier function, but unlike before and after, this has to be done manually in around. The basic blueprint of this is below, which is an example of an around modifier that exactly reproduces the original method (having no observable effect):


around 'fire_all' => sub {
       my ($orig, $self, @args) = @_;
       return $self->$orig(@args);
};

In an around modifier, the first argument is the method ($orig) instead of the object reference ($self) like in normal methods. Then, it's up to you to call the original method ($self->$orig) and capture its return value (or not) and then return.

Note:

The semicolons at the end of the method modifier definitions in the examples are required. Like all the keywords provided by Moose, the modifier sugar keywords actually are function calls and are not subroutine definitions. The modifier definitions are all just function calls with exactly two arguments: a string representing the name of the method to modify and a code reference to the actual modifier. CodeRefs are just treated syntactically as values like any other. It's not important to understand this fully to use method modifiers, but it is important to remember to use the semicolons.

Method modifiers make a great fit with Roles to define behaviors at a fine-grained level. Let's take a look at another example of a Role for our MyApp::Rifle class that makes use of method modifiers:


<![CDATA[
package MyApp::MightJam;
use Moose::Role;
use Moose::Util::TypeConstraints;

requires 'fire';

subtype 'Probability' => (
        as 'Num',
        where { $_ >= 0 && $_ <= 1 },
        message { "$_ is not a number between 0 and 1" }
);

has 'jam_probability' => ( 
        is => 'ro', 
        isa => 'Probability', 
        default => .01 
);

sub roll_dice {
        my $self = shift;
        return 1 if ( rand(1) < $self->jam_probability );
        return 0;
}

before 'fire' => sub {
        my $self = shift;
        die "Jammed!!!\n" if ($self->roll_dice);
};

1;
]]>

This Role adds the random chance of "Jamming" on any given call to "fire" depending on the probability specified in the jam_probability attribute (with the default probability set to 1%). I also illustrate here how to create a custom subtype, by defining a new type "Probability", which must be a number between 0 and 1.

You then could compose simple subclasses like the following:


package MyApp::CrappyRifle;
use strict;
use Moose;
extends 'MyApp::AutomaticRifle';
with 'MyApp::MightJam';

has '+jam_probability' => ( default => .5 );

1;

And:


package MyApp::NiceRifle;
use strict;
use Moose;
extends 'MyApp::AutomaticRifle';
with 'MyApp::MightJam';

has '+jam_probability' => ( default => .001 );

1;

The difference between these two is that CrappyRifle will jam on average 5 out 10 times, and NiceRifle will jam only 1 per 1,000 times.

Learning More

This article is just meant as an introduction to Moose, and because of space constraints, I have been able to cover only a few of its core features.

One of the other great things about Moose, and Perl in general, is the community and availability of documentation and resources. The Moose Manual, available on CPAN (see Resources), is well-written and comprehensive. There are also plenty of other docs and information available, and the number of them is growing every day as Moose continues to gain popularity.

If you get stuck on something and can't find the answer, try the #moose IRC channel on irc.perl.org. Many of the top experts are in this channel and are more than willing to help and answer questions. Although they will expect you to RTFM and have done your homework first, they will get you unstuck and pointed in the right direction.

If nothing else, I hope that this article has at least piqued your interest in modern development with Perl and Moose, and that you can see that Perl code can, in fact, be clean, easy to read and modern, while still being "Perlish" and powerful.

As you learn Moose, and modern Perl in general, be sure to check out some of the other projects and modules that are available, including Catalyst, Template::Toolkit, DBIx::Class, Try::Tiny, Test::More and Devel::NYTProf, just to name a few. You might be surprised what's out there, and what is really possible with Perl today.

Resources

Moose CPAN Page: http://search.cpan.org/perldoc?Moose

Moose Manual: http://search.cpan.org/perldoc?Moose::Manual

Moose::Util::TypeConstraints Documentation: http://search.cpan.org/perldoc?Moose::Util::TypeConstraints

Moose IRC Channel: #moose on irc.perl.org

perlreftut—Perl Reference Tutorial: http://perldoc.perl.org/perlreftut.html

Moose via Shutterstock.com

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I guess the basic question

ionutpop's picture

I guess the basic question this raises is whether ease of development for you beats usefulness to others. If that ticket is representative, it suggests that actual users feel that converting to Moose is transferring an unwelcome cost them, and so you might end up with modules that are easy to maintain, but unused. That more people might use Moose in the future is speculation, but this complaint is from an actual user.

Perhaps it would be better to wait for requests to Moose-ify existing modules, and if they don’t come, don’t bother. If converting to Moose is that simple, surely someone will send some patches to you, or fork the module, if they want a Moose version.

Instead, just consider Moose for new code, where there is no opportunity to encourage take-up by people looking for lightweight code, only to find it switched to what they think is heaviness after the fact.

Ianis from bet365.com

nice of artical Save the

juliajin's picture

nice of artical Save the aloft chic analogue into a book called MyApp/Rifle.pm aural one of your Perl's cover directories, and again you can use it in a Perl affairs like this. jogos de motos

Moose is awesome!

Chankey Pathak's picture

Thanks for this tutorial on Moose. Moose is simply awesome!

Intresting I have ner use

pilot school's picture

Intresting I have ner use Mose, but after reading this i might give it a try

----- http://ai.vc/zd

bdso8f9sa's picture

----- http://ai.vc/zd -----

Hi,Dear Ladies and Gentlemen,
1. sport shoes : Jordan ,Nike, adidas, Puma, Gucci, LV, UGG , etc. including women shoes and kids shoes.
2. T-Shirts : BBC T-Shirts, Bape T-Shirts, Armani T-Shirts, Polo T-Shirts,etc.
3. Hoodies : Bape hoody, hoody, AFF hoody, GGG hoody, ED hoody ,etc.
4. Jeans : Levis jeans , Gucci jeans, jeans, Bape jeans , DG jeans ,etc.
----- http://ai.vc/zd -----
----- http://ai.vc/zd -----

Service is our Lift.

enjoy yourself.

thank you!!

::∴★∵**☆.∴★∵**☆.∴★∵**☆.
█████.::∴★∵**☆.∴★∵**☆.
█田█田█::∴★∵**☆.∴★∵**☆.
█田█田█.∴★∵**☆.∴★∵**☆.
█田█田█∴★∵**☆.∴★∵**☆.
█田█田█.★∵**☆.∴★∵**☆.
█████.*******************
◢██□██◣.~~~~~*^_^*

thanx

Benzeb's picture

thanx for this article.
I've been laying with perl for some years now, but never gave a try to Moose.
Now that i have a clearer view to what Moose it, i have to try it

ps : Perl IS wonderful !! Can't understand why people enjoy php much more than Perl

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix