moose workshop
DESCRIPTION
Object Oriented got a lot easier since Moose came around. This keynote is a one-day advanced Moose workshop covering (almost) everything Moose has to offer perl developersTRANSCRIPT
![Page 2: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/2.jpg)
Agenda
•Moose Overview
• Classes
• Roles
• Attributes
•Meta Object System
• Type System
•Moose Extensions
•Design Patterns
Friday, July 6, 12
![Page 3: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/3.jpg)
Assumptions
• You know how to write a Moose classes
• You know how to define methods and what $self means
Friday, July 6, 12
![Page 4: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/4.jpg)
Moose Overview
•Developed by Stevan Little (on the right)
• Started 2006
• Goal: Change the world
Friday, July 6, 12
![Page 5: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/5.jpg)
Moose Features
• From perl to OO
•No boilerplate code
•Optional type constraints
• Inheritance and Mixins
•Design Patterns
Friday, July 6, 12
![Page 6: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/6.jpg)
Organizations Using Moose
• Cisco
• IMDb
• Infinity Interactive
•MusicBrainz
• Symantec
• And others: http://moose.iinteractive.com/about.html#organizations
Friday, July 6, 12
![Page 7: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/7.jpg)
Moose Alternatives
•Mouse
•Moo
•Mo
• Class::Builder
Friday, July 6, 12
![Page 8: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/8.jpg)
Moose HELP
• IRC: irc://irc.perl.org/#moose
•Mailing List: mailto:[email protected]
• Youtube: search for “perl moose”
Friday, July 6, 12
![Page 9: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/9.jpg)
Moose Classes
Friday, July 6, 12
![Page 10: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/10.jpg)
Moose Classes
• Import sugar functions: extends, has, with, ...
• Enable strict & warnings
• Subclass of Moose::Object for default ctor and dtor
• Create Moose::Meta::Class object
package Foo;use Moose;
Friday, July 6, 12
![Page 11: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/11.jpg)
Moose::Object
• new ( %params )
• BUILDARGS ( %params )
•DESTROY
• does( $role_name )
•DOES( $class_or_role_name )
• dump( $maxdepth )
Friday, July 6, 12
![Page 12: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/12.jpg)
Example: Getting Info
package Pet;use Moose;
has 'name', is => 'ro', isa => 'Str', default => 'Lassy';has 'past_owners', is => 'ro', isa => 'ArrayRef[Str]';
package main;
my $dog = Pet->new( past_owners => ['James', 'Mike'] );
# show dog's info. No need to import Data::Dumperwarn $dog->dump;
# DOES returns true for objects of the class, subclasses or# implementors of the roleprint "Good boy" if $dog->DOES('Pet');
Friday, July 6, 12
![Page 13: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/13.jpg)
Class Construction
• new method is automatically generated.
• Takes parameters hash or hash ref
package main;# Pass a hash ref to prevent copyingmy $enterprise = Starship->new( { captain => 'James T Kirk', crew => ['Dr. McCoy', 'Scott', 'Lt. Uhura'], });
Friday, July 6, 12
![Page 14: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/14.jpg)
Class Construction
• Construction hooks:
• BUILD
• BUILDARGS
• attribute builders
Friday, July 6, 12
![Page 15: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/15.jpg)
Class Construction
• BUILD is called every time a new object is created
• If inheritance is in effect, parent’s BUILD is called before child BUILD is called automatically
• Used for :
•Object state validation (whole object)
• Tracking objects creation
Friday, July 6, 12
![Page 16: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/16.jpg)
Object State Validation
package Starship;use Moose;
has 'captain', is => 'ro', isa => 'Str', required => 1;has 'crew', is => 'rw', isa => 'ArrayRef[Str]', required => 1;
sub BUILD { my $self = shift; if ( $self->captain ~~ $self->crew ) { my $captain = $self->captain; die "Validation Error: Cannot use $captain for both Captain and Crew"; }}
package main;
# Validation errormy $enterprise = Starship->new( { captain => 'James T Kirk', crew => ['Dr. McCoy', 'Scott', 'Lt. Uhura', 'James T Kirk'], });
Friday, July 6, 12
![Page 17: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/17.jpg)
BUILDARGS
• Used to manipulate arguments before object creation
• Takes the arguments hash as input, returns hashref
•Wrap in ‘around’ modifier to change
• Used for :
• Single arguments ctor
Friday, July 6, 12
![Page 18: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/18.jpg)
BUILDARGS Examplepackage Person;use Moose;
has 'name', is => 'ro', isa => 'Str', required => 1;
around BUILDARGS => sub { my $orig = shift; my $class = shift; my @params = @_;
# Sole parameter that is not a ref # is considered the name if ( ( @params == 1 ) && ( ! ref $params[0] ) ) { return $class->$orig( name => $params[0] ); } else { return $class->$orig ( @params ); }}; # Watch the semicolon
Friday, July 6, 12
![Page 19: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/19.jpg)
Class Destruction
•Moose implemented DESTROY, which will call your DEMOLISH
• It handles inheritance correctly: demolish child before super
Friday, July 6, 12
![Page 20: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/20.jpg)
Class Destruction
•When program ends, prints out:
Bar ::DemolishFoo::Demolish
package Foo;use Moose;
sub DEMOLISH { warn 'Foo::Demolish' }
package Bar;use Moose;extends 'Foo';
sub DEMOLISH { warn 'Bar::Demolish' }
package main;
my $b = Bar->new;
Friday, July 6, 12
![Page 21: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/21.jpg)
Construction Destruction
Do’s and Don’ts
Friday, July 6, 12
![Page 22: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/22.jpg)
Do
• Provide reasonable validations with BUILD
Friday, July 6, 12
![Page 23: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/23.jpg)
Do
• Use warn( $obj->dump ) for debug
Friday, July 6, 12
![Page 24: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/24.jpg)
Do
• Consider namespace::autoclean to remove Moose sugar methods from your classes (has, with, etc.)
Friday, July 6, 12
![Page 25: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/25.jpg)
Do
• Consider using:
__PACKAGE__->meta->make_immutable;
• To improve performance of objects creation
• Consider MooseX::AutoImmute
Friday, July 6, 12
![Page 26: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/26.jpg)
Don’t
•Never override new ( it’ll break stuff down the road )
Friday, July 6, 12
![Page 27: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/27.jpg)
Don’t
•Don’t use BUILD when attribute builders are sufficient
Friday, July 6, 12
![Page 28: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/28.jpg)
Don’t
•Never call $self->SUPER::BUILD
•Moose does that for you
Friday, July 6, 12
![Page 29: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/29.jpg)
Don’t
•Don’t apply a method modifier (before, after, around) to BUILD
Friday, July 6, 12
![Page 30: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/30.jpg)
Don’t
•Don’t write BUILD method for your roles ( Moose ignores them )
Friday, July 6, 12
![Page 31: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/31.jpg)
after
• Add code after a method is executed
• Receives: method name and subroutine to add
package Secret;use Mouse;
has 'message', is => 'ro', required => 1, clearer => 'reset';
has 'counter', is => 'rw', default => 3;
after 'message' => sub { my $self = shift; $self->counter( $self->counter - 1 ); if ( $self->counter <= 0 ) { $self->reset; }};
package main;my $secret = Secret->new( message => 'This message will self destroy');print $secret->message, "\n" for (1..5);
Friday, July 6, 12
![Page 32: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/32.jpg)
What Is Printed ?
package Foo;use Moose;
sub DEMOLISH { warn 'Foo::Demolish' }sub BUILD { warn 'Foo::Build' }
package Bar;use Moose;extends 'Foo';
sub DEMOLISH { warn 'Bar::Demolish' }sub BUILD { warn 'Bar::Build' }
package main;
my $b = Bar->new;
Friday, July 6, 12
![Page 33: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/33.jpg)
Method Modifiers
• Alter code by injecting other code before or after the modified method
• Can use from roles, subclasses or class itself
Friday, July 6, 12
![Page 34: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/34.jpg)
before
• Before lets us inject code before a method is called
• Spot the bug on the right
package Logger;use Mouse;
sub log { my $self = shift; my ($msg) = @_;
print $msg;}
before 'log' => sub { select *STDERR };after 'log' => sub { select *STDOUT };
package main;my $log = Logger->new;$log->log("hello\n");
Friday, July 6, 12
![Page 35: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/35.jpg)
around
• around has two more advantages:
• Can use return value of original method
• Can skip calling original method altogether
• You have the power
Friday, July 6, 12
![Page 36: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/36.jpg)
around
• First parameter: original method as CODE ref
• Second parameter is the object
• Can call $self->$orig to get requested functionality
package AroundExample;use Mouse;use feature ':5.10';
sub foo { print "In Foo\n" }
around 'foo' => sub { my $orig = shift; my $self = shift;
say "Around: before calling method"; $self->$orig(@_); say "Around: after calling method";};
Friday, July 6, 12
![Page 37: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/37.jpg)
around
• Forbid login before noon
package User;use Mouse;use DateTime;sub login { warn 'Welcome' }
around 'login' => sub { my $now = DateTime->now; if ( $now->hour < 12 ) { my $orig = shift; my $self = shift; $self->$orig(@_); }};
Friday, July 6, 12
![Page 38: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/38.jpg)
Friday, July 6, 12
![Page 39: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/39.jpg)
Moose RolesAn alternative to deep hierarchies and base classes
Friday, July 6, 12
![Page 40: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/40.jpg)
Role
• Encapsulates behavior. Something that classes do
• Cannot be instansiated
• Classes consume roles - which means everything in the role is copied into the class
Friday, July 6, 12
![Page 41: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/41.jpg)
Classes & Roles
Alive
Think Think
Alive
Person Computer Chicken
Friday, July 6, 12
![Page 42: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/42.jpg)
Roles Example
package Glass;use Moose;
with 'Breakable';
package main;my $g = Glass->new;
$g->break;$g->fix;
package Breakable;use Moose::Role;
has 'is_broken', is => 'rw', isa => 'Bool';
sub break { my $self = shift; print "Ouch\n" if ! $self->is_broken; $self->is_broken(1);}
sub fix { my $self = shift; print "Works now\n" if $self->is_broken; $self->is_broken(0);}
Friday, July 6, 12
![Page 43: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/43.jpg)
Moose Roles
• Use Moose::Role to define a role
• Use ‘with’ to consume a role
• Inside a role, define methods, attributes and modifiers
• Use ‘does’ to find out if an object implements a role
Friday, July 6, 12
![Page 44: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/44.jpg)
Partial Implementation
• Use ‘requires’ in a role to force your consumer to define a method
• Useful for :
• Partial implementations (template method)
• Abstract Base Class
Friday, July 6, 12
![Page 45: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/45.jpg)
Partial Implementationpackage MultipleFileUploader;use Moose::Role;
requires 'upload_file';
sub upload_files { my $self = shift;
my @success;
foreach my $f ( @_ ) { die "Invalid file: $f" if ! $f->DOES('File'); $self->upload_file ( $f ) && push @success, $f; }
return @success;}
Friday, July 6, 12
![Page 46: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/46.jpg)
Method Conflicts
• Consuming two roles with the same method names results in a conflict
• Class must then implement the conflicted method on its own
• Can call role implementation using their namespace
Friday, July 6, 12
![Page 47: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/47.jpg)
Method Conflicts
package R1;use Moose::Role;
sub foo { warn 'R1::foo'}
package R2;use Moose::Role;
sub foo { warn 'R2::foo'}
package Test;use Moose;
with qw/R1 R2/;
Compilation Error
Friday, July 6, 12
![Page 48: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/48.jpg)
Method Conflict
• Can use -alias to make a copy of a role’s method by another name
• Can use -excludes to avoid consuming a specific method
• Combine both to work around a conflict
Friday, July 6, 12
![Page 49: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/49.jpg)
Method Conflict
with 'Breakable' => { -alias => { break => 'break_bone' }, -excludes => 'break', },
'Breakdancer' => { -alias => { break => 'break_dance' }, -excludes => 'break', };
Friday, July 6, 12
![Page 50: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/50.jpg)
Dynamic Roles
• Roles can be added to instances after creation
• Usage: debug tracing on specific obejct, dynamically change objects by configuration
• Code:
use Moose::Util qw( apply_all_roles );
my $car = Car->new; apply_all_roles( $car, 'Breakable' );
Friday, July 6, 12
![Page 51: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/51.jpg)
Lab
• Implement a Comparable role which requires a single method: compare($other) - returns -1 if $other is greater than $self; 0 if they are equal and +1 if $self is greater.
• Use compare to implement the following: greater_than, greater_or_equal, less_than, less_or_equal
• Implement a class that consumes the role
Friday, July 6, 12
![Page 52: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/52.jpg)
Friday, July 6, 12
![Page 53: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/53.jpg)
Attributes
Friday, July 6, 12
![Page 54: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/54.jpg)
Moose Attributes
• An attribute is a property that every member of a class has
• Some attributes are optional (e.g. some people have a middle name)
Friday, July 6, 12
![Page 55: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/55.jpg)
Attribute Options
• is, reader, writer
• isa
• required, default, builder
• lazy
Friday, July 6, 12
![Page 56: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/56.jpg)
Readers & Writers
• Use ‘is’ to auto generate reader/writer
• Use ‘writer’ to specify writer’s name
• Use ‘reader’ to specify reader’s name
package Product;use Moose;
has 'name' => ( is => 'rw', reader => 'get_name', writer => '_set_name',);
has 'price' => ( is => 'rw', reader => 'get_price', writer => 'set_price',);
Friday, July 6, 12
![Page 57: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/57.jpg)
Isa
• Use isa to force a type constraint
• Available Types include: Bool, Str, Num, Int, ScalarRef, ArrayRef, HashRef, CodeRef
• Can use another object as type constraint
•Many more type constraints with option to extend the list yourself
Friday, July 6, 12
![Page 58: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/58.jpg)
Isa
package Store;use Moose;use Client;use Product;
has 'owner', is => 'ro', isa => 'Str';
has 'clients', is => 'rw', isa => 'ArrayRef[Client]';has 'products', is => 'rw', isa => 'ArrayRef[Product]';
has 'revenue', is => 'rw', isa => 'Num';
1;
Friday, July 6, 12
![Page 59: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/59.jpg)
Subtypes
• Use subtypes to easily define new constraints:
use Moose::Util::TypeConstraints;
subtype 'Age', as 'Int', where { $_ >= 0 && $_ <= 120 }, message { "Invalid Age: $_ "};
Friday, July 6, 12
![Page 60: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/60.jpg)
Enumerations
• Use enum function to declare an enum subtype
• An enum takes a single value from a predefined list
enum 'EyeColor', [qw/green blue brown gray/];
Friday, July 6, 12
![Page 61: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/61.jpg)
Required / Default / Builder
• Use required for fields that take their value from “outside”
• Use default / builder for everything else
Friday, July 6, 12
![Page 62: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/62.jpg)
Builder
• Use builder for more complex initialization logic
• builder works better than default for inheritance
package Person;use Moose;
has 'pet', is => 'ro', builder => '_build_pet';
has 'age', is => 'rw', required => 1;
sub _build_pet { my $self = shift; if ( $self->age < 13 ) { return "None"; } else { return "Dog"; }}
package main;my $p = Person->new(age => 10);print $p->pet;
Friday, July 6, 12
![Page 63: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/63.jpg)
lazy
• Create your attributes only when they are needed
• Use lazy_build to type less
package Person;use Moose;
has 'pet', is => 'ro', lazy_build => 1;has 'age', is => 'rw', required => 1;
sub _build_pet { my $self = shift; if ( $self->age < 13 ) { return "None"; } else { return "Dog"; }}
package main;my $p = Person->new(age => 10);print $p->pet;
Friday, July 6, 12
![Page 64: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/64.jpg)
Dependency Injection
• A technique used in testing to build more testable versions of your classes
• If an attribute has both a builder AND was passed externally, external value wins
Friday, July 6, 12
![Page 65: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/65.jpg)
Lab
• Implement a Logger class with one method: log. In the ctor, logger can take a file name
• If no arguments passed, create a screen logger (write all output to screen)
• If a file name was provided, write to that file
• Use dependency injection to test your Logger
Solution: https://gist.github.com/3029901
Friday, July 6, 12
![Page 66: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/66.jpg)
Delegation
• A relationship between classes. A class attribute is an object of a different class
• Can then redirect all calls on containing object to the attribute - thus delegating specific methods
Friday, July 6, 12
![Page 67: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/67.jpg)
Delegation
Contact EmailSend Mail Send Mail
Phone
CallCall
Friday, July 6, 12
![Page 68: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/68.jpg)
Delegation
•Moose handles delegation for you
• Attribute should declare “handles” option
package Contact;use Moose;
has 'email' => ( is => 'ro', handles => [ qw/send_mail/ ]);
Friday, July 6, 12
![Page 69: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/69.jpg)
Delegate
• Another option is to delegate an entire role
•Moose will delegate all methods in the role automatically
has 'uri' => ( is => 'ro', isa => 'URI', handles => 'HasURI',);
Friday, July 6, 12
![Page 70: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/70.jpg)
Native Delegation
• Give your object “native” feel by using standard data type methods
• Currently supported: Array, Hash, Number, String, Bool, Counter
• Useful for : Fields that should “work like” the native data type
Friday, July 6, 12
![Page 71: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/71.jpg)
Native Delegation
•Native arrays have push, pop, shift, unshift and more
• Can now use:$q->add_itemto add an item to the queue
has 'q' => ( is => 'ro', isa => 'ArrayRef[Int]', default => sub { [] }, traits => [qw/Array/], handles => { add_item => 'push', next_item => 'shift', },);
package main;my $q = Queue->new;$q->add_item(10, 20);
Friday, July 6, 12
![Page 72: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/72.jpg)
Native Delegation
• Array functions: Moose::Meta::Attribute::Native::Trait::Array
•Hash functions:Moose::Meta::Attribute::Native::Trait::Hash
Friday, July 6, 12
![Page 73: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/73.jpg)
Friday, July 6, 12
![Page 74: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/74.jpg)
Attributes: Advanced Topics
• Predicates & Clearers
• Constructor Parameters
•Weak References
• Triggers
Friday, July 6, 12
![Page 75: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/75.jpg)
Predicates & Clearers
• User can upload photos, other users can “like”
• Every photo starts with 0 likes
• How many “likes” do you have before the image is online ?
Uploading ImageNo likes yet
Image Online0 Likes.
Go find more friends
Friday, July 6, 12
![Page 76: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/76.jpg)
Predicates & Clearers
• Provide two new methods on $self: unpublish and is_published
• Setting value to undef does not affect predicate
package Photo;use Moose;
has 'likes' => ( is => 'rw', clearer => 'unpublish', predicate => 'is_published',);
sub publish { my $self = shift; $self->likes ( 0 );}
Friday, July 6, 12
![Page 77: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/77.jpg)
Predicates & Clearers
sub like { my $self = shift;
die 'Cannot like an Unpublished photo' if ! $self->is_published;
$self->likes ( $self->likes + 1 );}
Friday, July 6, 12
![Page 78: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/78.jpg)
Constructor Parameters
• Sometimes the name of the attribute is not the same as the name of the constructor param
• A possible workaround is BUILDARGS, but that’s too tedious
• A better way: Use init_arg
• Usage: modify constructor param name, prevent dependency injection
Friday, July 6, 12
![Page 79: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/79.jpg)
Example: init_arg
• Use to modify constructor parameter name
• Attribute name is size, while object creation is performed with:Cls->new( bigness => 7 )
has 'bigness' => ( is => 'ro', init_arg => 'size', );
Friday, July 6, 12
![Page 80: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/80.jpg)
Example: init_arg
• Use init_arg => undef to prevent dependency injection
• Use with caution
has '_genetic_code' => ( is => 'ro', lazy_build => 1, init_arg => undef, );
Friday, July 6, 12
![Page 81: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/81.jpg)
Weak References
Course
Student Student Student
Learns At
Friday, July 6, 12
![Page 82: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/82.jpg)
Weak References
•When an object leaves scope, it’s ref-count decreases
• Circular references cause objects to remain in memory
•Weak references to the rescue
Friday, July 6, 12
![Page 83: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/83.jpg)
Weak Ref
•When a Course object leaves the last scope - it will now be deleted
•When Course object leaves scope, Moose will automatically clear all “learns_at” attributes of students
package Student;use Moose;has 'name', is => 'ro', required => 1;
has 'learns_at', is => 'rw', weak_ref => 1;
Full Example: https://gist.github.com/3031636Friday, July 6, 12
![Page 84: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/84.jpg)
Triggers
• Called when attribute value is set
• Called when set from new or explicitly
• Is not called when set from default or builder
has 'size' => ( is => 'rw', trigger => \&_size_set,);
sub _size_set { my ( $self, $size, $old_size ) = @_;}
Friday, July 6, 12
![Page 85: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/85.jpg)
Friday, July 6, 12
![Page 86: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/86.jpg)
Lab
• Improve Students/Course example to use native delegation
• Use method modifiers to add custom logic
Friday, July 6, 12
![Page 87: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/87.jpg)
Meta Moose
Friday, July 6, 12
![Page 88: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/88.jpg)
What is MOP
• An abstraction to build abstractions - or simply put - an API to build an object system
•Moose is one object system built upon Class::MOP
• Understanding Class::MOP and Moose’s use of it reveals new features in Moose
Friday, July 6, 12
![Page 89: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/89.jpg)
MOP Parts
• The Class protocol
• The Attribute protocol
• The Method protocol
• The Instance protocol
Friday, July 6, 12
![Page 90: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/90.jpg)
Moose and Class::MOP
•Moose is built on top of Class::MOP
• Prefixed Moose::Meta (for example Moose::Meta::Class)
• Get with $self->meta
Friday, July 6, 12
![Page 91: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/91.jpg)
What Meta Can Do For You
• Class and Object Introspection
•Modify objects and classes dynamically (add/remove methods, attributes, roles)
• Add more information to attributes (label, persistent)
Friday, July 6, 12
![Page 92: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/92.jpg)
Object Introspection
package main;
my $z = Zombie->new;
for my $attr ( $z->meta->get_all_attributes ) { say $attr->name;}
for my $method ( $z->meta->get_all_methods ) { say $method->fully_qualified_name;}
if ( $z->meta->has_method( 'eat_brain' ) ) { $z->eat_brain;}
Full Source: https://gist.github.com/3032056Friday, July 6, 12
![Page 93: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/93.jpg)
Object Introspection
• All meta methods listed under:
Class::MOP::Class and Moose::META::Class
• In most cases, using roles is a better idea than dynamic checking
Friday, July 6, 12
![Page 94: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/94.jpg)
Validate Type Constraints
• Use $self->meta->get_attribtue(attr)->type_constraint to get meta object of type constraints
• $constraint->check( $value )
• $constraint->validate( $value ) or die $constraint->get_message( $value );
• $constraint->assert_valid( $value )
Friday, July 6, 12
![Page 95: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/95.jpg)
Class Modification
• $meta->add_attribute
• $meta->remove_attribute
• $meta->add_method
• $meta->remove_method
• $meta->make_immutable
Friday, July 6, 12
![Page 96: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/96.jpg)
Moose::Util
• A bundle of useful functions that take away some of the pain of working with meta
• Start here before implementing your own.
Friday, July 6, 12
![Page 97: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/97.jpg)
Moose::Util
• find_meta( $class_or_obj )
• does_role( $class_or_obj, $role )
• apply_all_roles( $applicant, @roles )
• english_list( @items )
Friday, July 6, 12
![Page 98: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/98.jpg)
Friday, July 6, 12
![Page 99: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/99.jpg)
Moose TypesCustomizable Type System
Friday, July 6, 12
![Page 100: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/100.jpg)
Moose Type System
• Verify attribute values are “valid” - of a certain type
• Types have names, so they can be reused
• Type checking is just sugar for method arguments validation. Perl does not associate types with variables
• Earlier error detection
Friday, July 6, 12
![Page 101: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/101.jpg)
Stock Types
• Bool, Maybe[‘a], Str, Num, Int, ClassName, RoleName
• Ref, ScalarRef[‘a], ArrayRef[‘a], HashRef[‘a], CodeRef
• RegexpRef, GlobRef, FileHandle
•Object
Friday, July 6, 12
![Page 102: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/102.jpg)
Type Registry
• A type is an instance of Moose::Meta::TypeConstraint
• All types are stored in the type registry. Use get_type_constraint_registry from Moose::Util::TypeConstraints to get it
Friday, July 6, 12
![Page 103: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/103.jpg)
Example: Print All Constraints
use v5.14;use Data::Dumper;use Moose::Util::TypeConstraints;
my $registry = Moose::Util::TypeConstraints::get_type_constraint_registry();
print Dumper($registry->type_constraints);
Friday, July 6, 12
![Page 104: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/104.jpg)
Extending The Type System
• Every Moose object is a new type
• There are also helper methods to create new types
• A new type can be named or anonymous
Friday, July 6, 12
![Page 105: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/105.jpg)
Named Subtypes: enum
use v5.14;
package Person::Types;use Moose::Util::TypeConstraints;
enum 'Person::Types::EyeColor', [qw/gray brown green blue/];
package Person;use Moose;use Moose::Util::TypeConstraints;
has 'eyecolor' => ( is => 'ro', isa => 'Person::Types::EyeColor',);
Friday, July 6, 12
![Page 106: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/106.jpg)
Anonymous Subtypes: enum
use v5.14;
package Person;use Moose;use Moose::Util::TypeConstraints;
has 'eyecolor' => ( is => 'ro', isa => enum [qw/gray blue brown green/],);
Friday, July 6, 12
![Page 107: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/107.jpg)
More Subtypes
• subtype( %opts ) - Create a new subtype
• role_type ‘barks’, { role => ‘Some::Library::Role::Barks’ }
• union ‘UnionName’, [qw/Str ArrayRef/]; - Create a new subtype that can hold either string or an array
Friday, July 6, 12
![Page 108: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/108.jpg)
Subtypes
• Provide ‘as’ to specify base type
• Provide ‘where’ to add constraint on the base type
• Provide your own error message with ‘message’
subtype 'NaturalLessThanTen', as 'Natural', where { $_ < 10 }, message { "This number ($_) is not less than ten!" };
Friday, July 6, 12
![Page 109: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/109.jpg)
Subtypes Do’s
•Define all your subtype in a single module for code reuse. Use that module from every Moose class
Friday, July 6, 12
![Page 110: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/110.jpg)
Subtypes Do’s
• Prefer namespaced subtypes: ZombieApocalipse::Human::EyeColor is better thanEyeColor
• Zombies may have different eye color ...
Friday, July 6, 12
![Page 111: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/111.jpg)
Type CoercionProceed With Caution
Friday, July 6, 12
![Page 112: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/112.jpg)
Type Coercion
• Automatically convert invalid data to valid
• Int ------> ArrayRef[Int]
• Str ------> Person
• High risk - an invalid value could coerce thus skipping type validation
Friday, July 6, 12
![Page 113: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/113.jpg)
Type Coercion
use v5.14;
package Student;use Moose;use Moose::Util::TypeConstraints;
subtype 'GradesArray', as 'ArrayRef[Int]';coerce 'GradesArray', from 'Int', via { [ $_ ] };
has 'grades', is => 'ro', isa => 'GradesArray', coerce => 1;
package main;my $s = Student->new( grades => 77 );
print $s->dump;
Friday, July 6, 12
![Page 114: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/114.jpg)
Coercion Don’ts
•Don’t add coercion on Moose’s subtypes (unfortunately it’ll work)
• Generally, try to avoid coercions
Friday, July 6, 12
![Page 115: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/115.jpg)
Friday, July 6, 12
![Page 116: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/116.jpg)
Subtypes Lab
•Define a new subtype for hex numbers (numbers of the format 0x22)
• Add a coercion from HexNum to Int
Friday, July 6, 12
![Page 117: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/117.jpg)
MooseXMore Than Moose
Friday, July 6, 12
![Page 118: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/118.jpg)
eXtending Moose
•Moose is (relatively) easy to change and extend
•Writing extensions can take some time and effort BUT
• There are tons of Moose Extensions on CPAN
• Prefixed MooseX, they provide extra or modified functionality
Friday, July 6, 12
![Page 119: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/119.jpg)
Useful MooseX
•MooseX::StrictConstructor
•MooseX::Singleton
•MooseX::Declare
•MooseX::FollowPBP
•MooseX::Privacy
•MooseX::SingleArg
•MooseX::MultiMethods
•MooseX::HasDefaults
•MooseX::APIRole
Friday, July 6, 12
![Page 120: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/120.jpg)
Simple eXtensions
•MooseX::StrictConstructor
•MooseX::Singleton
•MooseX::FollowPBP
•MooseX::SingleArg
•MooseX::HasDefaults
•MooseX::Privacy
Friday, July 6, 12
![Page 121: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/121.jpg)
MooseX::StrictConstructor
• Throw exception if constructor was passed an unexpected argument
package Contact;use Moose;use MooseX::StrictConstructor;
has 'email', is => 'ro';has 'name', is => 'ro';
package main;
# Throw an exceptionContact->new( name => 'Bob', emial => '[email protected]');
Friday, July 6, 12
![Page 122: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/122.jpg)
MooseX::Singleton
• Create only one instance of a class
• Has initialization method to pass arguments if needed
package App;use MooseX::Singleton;
package main;
{ my $app = App->instance;}
{ # same one my $app = App->instance;}
Friday, July 6, 12
![Page 123: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/123.jpg)
MooseX::FollowPBP
• Use set_x and get_x as default reader and writer
• SEE ALSO: Perl::Critic
Friday, July 6, 12
![Page 124: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/124.jpg)
MooseX::SingleArg
• Easily create single arg constructor (without wrapping BUILDARGS)
use v5.14;
package Contact;use Moose;use MooseX::SingleArg;
single_arg 'name';has 'name', is => 'ro';
package main;my $c = Contact->new('Mike');
say $c->name;
Friday, July 6, 12
![Page 125: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/125.jpg)
MooseX::HasDefaults
• Automatically use:
is => ‘ro’
or :
is => ‘rw’
use v5.14;
package Point;use Moose;use MooseX::HasDefaults::RO;
has ['x', 'y', 'z'];
Friday, July 6, 12
![Page 126: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/126.jpg)
MooseX::Privacy
• Restrict visibility of methods
• private can only be called from within the class
• protected can only be called from within the class or any of its subclasses
•Doesn’t work for roles
use MooseX::Privacy; has config => ( is => 'rw', isa => 'Some::Config', traits => [qw/Private/],); private_method foo => sub { return 23;}; protected_method bar => sub { return 42;};
Friday, July 6, 12
![Page 127: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/127.jpg)
Heavy Lifting
• Logging: Log4perl
•MooseX::APIRole
•MooseX::Declare
•MooseX::MultiMethods
Friday, July 6, 12
![Page 128: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/128.jpg)
Log4perl
• Logging is all about keeping a record of your info at runtime
• Log4perl lets you control how your application logs its data
• Perl’s implementation of log4j
Friday, July 6, 12
![Page 129: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/129.jpg)
Log4perl alternatives
• print/warn debug messages: Too simple for real apps
• roll-your-own: Too much work...
• Log4perl is currently the best logging solution for medium-large perl applications
Friday, July 6, 12
![Page 130: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/130.jpg)
Log4perl and Moose
• Use MooseX::Log::Log4perl role in your class
•New attributes: log and logger
package MyApp;use Moose;
with 'MooseX::Log::Log4perl';
sub go { my $self = shift;
$self->log->debug('Starting method go'); $self->log->info('Go go go');
$self->log('IO')->info('reading data');}
Friday, July 6, 12
![Page 131: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/131.jpg)
Log4perl Output
• Completely customizable
•Output log to: Screen, File, Socket, DBI, and more
• Example:
[2012/07/06 14:54:34] 130.pl MyApp::go 130.pl (9) MyApp - Starting method go[2012/07/06 14:54:34] 130.pl MyApp::go 130.pl (10) MyApp - Go go go[2012/07/06 14:54:34] 130.pl MyApp::go 130.pl (12) IO - reading data
Friday, July 6, 12
![Page 132: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/132.jpg)
Log4perl Configuration
log4perl.logger = DEBUG, Screen, Logfile
log4perl.appender.Screen = Log::Log4perl::Appender::Screenlog4perl.appender.Screen.layout = PatternLayoutlog4perl.appender.Screen.layout.ConversionPattern= \ [%r] %F %l %c - %m%n
log4perl.appender.Logfile = Log::Log4perl::Appender::Filelog4perl.appender.Logfile.filename = my.loglog4perl.appender.Logfile.layout = PatternLayoutlog4perl.appender.Logfile.layout.ConversionPattern = \ [%d] %F %l %c - %m%n
Friday, July 6, 12
![Page 133: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/133.jpg)
Log4perl Initialization
• Load configuration file on startup with: Log::Log4perl::init(filename)
package main;use Log::Log4perl;
Log::Log4perl::init('log.conf');
Friday, July 6, 12
![Page 134: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/134.jpg)
Log4perl Docs
• Usage: perldoc Log::Log4perl
• Conversion Patterns Layout:http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html
Friday, July 6, 12
![Page 135: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/135.jpg)
MooseX::APIRole
• Automatically create a role out of a class
• all subroutines become ‘requires’
• Easy to use and very powerful
package Logger;use Moose;use MooseX::APIRole;
sub info { }sub error { }
make_api_role 'Logger::API';
package Test;use Moose;# Fails - Test does not implement# required methodswith 'Logger::API';
Friday, July 6, 12
![Page 136: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/136.jpg)
MooseX::Declare
• Use modern OO syntax for your moose objects
• ‘class’ keywords declares a class. Inside, MooseX::Method::Signatures is in effect.
• ‘role’ keyword declares a role
Friday, July 6, 12
![Page 137: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/137.jpg)
MooseX::Declare
use MooseX::Declare;
class BankAccount { has 'balance' => ( isa => 'Num', is => 'rw', default => 0 );
method deposit (Num $amount) { $self−>balance( $self−>balance + $amount ); }
method withdraw (Num $amount) { my $current_balance = $self−>balance(); ( $current_balance >= $amount ) || confess "Account overdrawn"; $self−>balance( $current_balance − $amount ); }}
Friday, July 6, 12
![Page 138: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/138.jpg)
MooseX::Declare
• Still experimental, API could change
• Inside a method $self is already defined for you, as well as other input parameters
• Awesome. perldoc MooseX::Declare for more
Friday, July 6, 12
![Page 139: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/139.jpg)
MooseX::MultiMethods
• Allow multi methods dispatcher based on input arguments
•Define multiple handlers instead of long if-else blocks
Friday, July 6, 12
![Page 140: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/140.jpg)
MooseX::MultiMethods
package Paper; use Moose;package Scissors; use Moose;package Rock; use Moose;
package Game;use Moose;use MooseX::MultiMethods;
multi method play (Paper $x, Rock $y) { 1 }multi method play (Scissors $x, Paper $y) { 1 }multi method play (Rock $x, Scissors $y) { 1 }multi method play (Any $x, Any $y) { 0 }
my $game = Game->new;
# 1, Paper covers Rockprint $game->play(Paper->new, Rock->new);
Friday, July 6, 12
![Page 141: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/141.jpg)
Friday, July 6, 12
![Page 142: Moose workshop](https://reader031.vdocuments.net/reader031/viewer/2022012401/554f492cb4c905524c8b4836/html5/thumbnails/142.jpg)
Thanks For Listening
• Ynon Perek
• ynonperek.com
Friday, July 6, 12