Moose workshop
Upcoming SlideShare
Loading in...5
×
 

Moose workshop

on

  • 1,668 views

Object Oriented got a lot easier since Moose came around.

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 developers

Statistics

Views

Total Views
1,668
Views on SlideShare
1,668
Embed Views
0

Actions

Likes
1
Downloads
23
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Moose workshop Moose workshop Presentation Transcript

  • Moose Workshop Ynon Perek ynonperek@yahoo.com http://ynonperek.comFriday, July 6, 12
  • Agenda • Moose Overview • Moose Extensions • Classes • Design Patterns • Roles • Attributes • Meta Object System • Type SystemFriday, July 6, 12
  • Assumptions • You know how to write a Moose classes • You know how to define methods and what $self meansFriday, July 6, 12
  • Moose Overview • Developed by Stevan Little (on the right) • Started 2006 • Goal: Change the worldFriday, July 6, 12
  • Moose Features • From perl to OO • No boilerplate code • Optional type constraints • Inheritance and Mixins • Design PatternsFriday, July 6, 12
  • Organizations Using Moose • Cisco • IMDb • Infinity Interactive • MusicBrainz • Symantec • And others: http://moose.iinteractive.com/ about.html#organizationsFriday, July 6, 12
  • Moose Alternatives • Mouse • Moo • Mo • Class::BuilderFriday, July 6, 12
  • Moose HELP • IRC: irc://irc.perl.org/#moose • Mailing List: mailto:moose- subscribe@perl.org • Youtube: search for “perl moose”Friday, July 6, 12
  • Moose ClassesFriday, July 6, 12
  • Moose Classes • Import sugar functions: extends, has, with, ... package Foo; • Enable strict & warnings use Moose; • Subclassof Moose::Object for default ctor and dtor • Create Moose::Meta::Class objectFriday, July 6, 12
  • Moose::Object • new ( %params ) • BUILDARGS ( %params ) • DESTROY • does( $role_name ) • DOES( $class_or_role_name ) • dump( $maxdepth )Friday, July 6, 12
  • 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 dogs info. No need to import Data::Dumper warn $dog->dump; # DOES returns true for objects of the class, subclasses or # implementors of the role print "Good boy" if $dog->DOES(Pet);Friday, July 6, 12
  • Class Construction package main; • new method is automatically # Pass a hash ref to prevent copying generated. my $enterprise = Starship->new( {         captain => James T Kirk,         crew => [Dr. McCoy, • Takes parameters hash or Scott, Lt. Uhura], hash ref     });Friday, July 6, 12
  • Class Construction • Construction hooks: • BUILD • BUILDARGS • attribute buildersFriday, July 6, 12
  • 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 creationFriday, July 6, 12
  • 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 error my $enterprise = Starship->new( {         captain => James T Kirk,         crew => [Dr. McCoy, Scott, Lt. Uhura, James T Kirk],     });Friday, July 6, 12
  • 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 ctorFriday, July 6, 12
  • BUILDARGS Example package 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 semicolonFriday, July 6, 12
  • Class Destruction • Moose implemented DESTROY, which will call your DEMOLISH • It handles inheritance correctly: demolish child before superFriday, July 6, 12
  • Class Destruction package Foo; use Moose; sub DEMOLISH { warn Foo::Demolish } • When program package Bar; ends, prints out: use Moose; extends Foo; Bar::Demolish sub DEMOLISH { warn Bar::Demolish } Foo::Demolish package main; my $b = Bar->new;Friday, July 6, 12
  • Construction Destruction Do’s and Don’tsFriday, July 6, 12
  • Do • Provide reasonable validations with BUILDFriday, July 6, 12
  • Do • Use warn( $obj->dump ) for debugFriday, July 6, 12
  • Do • Consider namespace::autoclean to remove Moose sugar methods from your classes (has, with, etc.)Friday, July 6, 12
  • Do • Consider using: __PACKAGE__->meta->make_immutable; • To improve performance of objects creation • Consider MooseX::AutoImmuteFriday, July 6, 12
  • Don’t • Never override new ( it’ll break stuff down the road )Friday, July 6, 12
  • Don’t • Don’t use BUILD when attribute builders are sufficientFriday, July 6, 12
  • Don’t • Never call $self->SUPER::BUILD • Moose does that for youFriday, July 6, 12
  • Don’t • Don’t apply a method modifier (before, after, around) to BUILDFriday, July 6, 12
  • Don’t • Don’t write BUILD method for your roles ( Moose ignores them )Friday, July 6, 12
  • after package Secret; use Mouse; has message, is => ro, required => 1, clearer => reset; • Add code after a method is has counter, is => rw, default => 3; executed after message => sub {     my $self = shift;     $self->counter( $self->counter - 1 ); • Receives: method name and     if ( $self->counter <= 0 ) {         $self->reset; subroutine to add     } }; package main; my $secret = Secret->new( message => This message will self destroy); print $secret->message, "n" for (1..5);Friday, July 6, 12
  • 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
  • Method Modifiers • Alter code by injecting other code before or after the modified method • Can use from roles, subclasses or class itselfFriday, July 6, 12
  • before package Logger; use Mouse; sub log {     my $self = shift; • Before lets us inject code     my ($msg) = @_; before a method is called     print $msg; } before log => sub { select *STDERR }; • Spot the bug on the right after log => sub { select *STDOUT }; package main; my $log = Logger->new; $log->log("hellon");Friday, July 6, 12
  • around • around has two more advantages: • Can use return value of original method • Can skip calling original method altogether • You have the powerFriday, July 6, 12
  • around • First parameter: original package AroundExample; use Mouse; method as CODE ref use feature :5.10; sub foo { print "In Foon" } • Second parameter is the around foo => sub {     my $orig = shift; object     my $self = shift;     say "Around: before calling method"; • Can call $self->$orig to get     $self->$orig(@_);     say "Around: after calling method"; requested functionality };Friday, July 6, 12
  • around package User; use Mouse; use DateTime; sub login { warn Welcome } around login => sub {     my $now = DateTime->now;     if ( $now->hour < 12 ) { • Forbid login before noon         my $orig = shift;         my $self = shift;         $self->$orig(@_);     } };Friday, July 6, 12
  • Friday, July 6, 12
  • Moose Roles An alternative to deep hierarchies and base classesFriday, July 6, 12
  • Role • Encapsulates behavior. Something that classes do • Cannot be instansiated • Classes consume roles - which means everything in the role is copied into the classFriday, July 6, 12
  • Classes & Roles Person Computer Chicken Alive Alive Think ThinkFriday, July 6, 12
  • Roles Example package Breakable; use Moose::Role; package Glass; has is_broken, is => rw, isa => Bool; use Moose; sub break {     my $self = shift; with Breakable;     print "Ouchn" if ! $self->is_broken;     $self->is_broken(1); } package main; my $g = Glass->new; sub fix {     my $self = shift;     print "Works nown" if $self->is_broken; $g->break;     $self->is_broken(0); $g->fix; }Friday, July 6, 12
  • 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 roleFriday, July 6, 12
  • Partial Implementation • Use ‘requires’ in a role to force your consumer to define a method • Useful for: • Partial implementations (template method) • Abstract Base ClassFriday, July 6, 12
  • Partial Implementation package 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
  • 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 namespaceFriday, July 6, 12
  • Method Conflicts package R1; package Test; use Moose::Role; use Moose; sub foo { with qw/R1 R2/;     warn R1::foo } package R2; Compilation Error use Moose::Role; sub foo {     warn R2::foo }Friday, July 6, 12
  • 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 conflictFriday, July 6, 12
  • Method Conflict with Breakable => { -alias => { break => break_bone }, -excludes => break, }, Breakdancer => { -alias => { break => break_dance }, -excludes => break, };Friday, July 6, 12
  • 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
  • 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 roleFriday, July 6, 12
  • Friday, July 6, 12
  • AttributesFriday, July 6, 12
  • 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
  • Attribute Options • is, reader, writer • isa • required, default, builder • lazyFriday, July 6, 12
  • Readers & Writers package Product; use Moose; • Use ‘is’ to auto generate has name => ( reader/writer     is => rw,     reader => get_name, • Use ‘writer’ to specify     writer => _set_name, ); writer’s name has price => (     is => rw, • Use ‘reader’ to specify     reader => get_price, reader’s name     writer => set_price, );Friday, July 6, 12
  • 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 yourselfFriday, July 6, 12
  • 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
  • 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
  • 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
  • Required / Default / Builder • Use required for fields that take their value from “outside” • Use default / builder for everything elseFriday, July 6, 12
  • Builder package Person; use Moose; has pet, is => ro, builder => _build_pet; • Use builder for more has age, is => rw, required => 1; complex initialization logic sub _build_pet {     my $self = shift;     if ( $self->age < 13 ) {         return "None"; • builder works better than     } else {         return "Dog"; default for inheritance     } } package main; my $p = Person->new(age => 10); print $p->pet;Friday, July 6, 12
  • lazy package Person; use Moose; has pet, is => ro, lazy_build => 1; has age, is => rw, required => 1; sub _build_pet { • Create your attributes only     my $self = shift;     if ( $self->age < 13 ) { when they are needed         return "None";     } else {         return "Dog"; • Use lazy_build to type less     } } package main; my $p = Person->new(age => 10); print $p->pet;Friday, July 6, 12
  • 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 winsFriday, July 6, 12
  • 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/3029901Friday, July 6, 12
  • 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 methodsFriday, July 6, 12
  • Delegation Send Mail Send Mail Contact Email Call Call PhoneFriday, July 6, 12
  • Delegation package Contact; use Moose; • Moose handles delegation for you has email => (     is => ro,     handles => [ qw/send_mail/ ] • Attribute should declare ); “handles” optionFriday, July 6, 12
  • Delegate • Another option is to has uri => ( is => ro, delegate an entire role isa => URI, handles => HasURI, ); • Moose will delegate all methods in the role automaticallyFriday, July 6, 12
  • 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 typeFriday, July 6, 12
  • Native Delegation has q => (     is => ro,     isa => ArrayRef[Int],     default => sub { [] }, • Native arrays have push,     traits => [qw/Array/], pop, shift, unshift and more     handles => {         add_item => push,         next_item => shift, • Can now use:     }, $q->add_item ); to add an item to package main; the queue my $q = Queue->new; $q->add_item(10, 20);Friday, July 6, 12
  • Native Delegation • Array functions: Moose::Meta::Attribute::Native::Trait::Array • Hash functions: Moose::Meta::Attribute::Native::Trait::HashFriday, July 6, 12
  • Friday, July 6, 12
  • Attributes: Advanced Topics • Predicates & Clearers • Constructor Parameters • Weak References • TriggersFriday, July 6, 12
  • Predicates & Clearers • User can upload photos, Uploading Image other users can “like” No likes yet • Every photo starts with 0 likes Image Online • How many “likes” do you 0 Likes. have before the image is online ? Go find more friendsFriday, July 6, 12
  • Predicates & Clearers package Photo; use Moose; has likes => ( • Provide two new methods     is => rw, on $self: unpublish and     clearer => unpublish,     predicate => is_published, is_published ); • Setting value to undef does sub publish {     my $self = shift; not affect predicate     $self->likes ( 0 ); }Friday, July 6, 12
  • 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
  • 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 injectionFriday, July 6, 12
  • Example: init_arg • Use to modify constructor parameter name has bigness => ( is => ro, • Attribute name is size, while init_arg => size, ); object creation is performed with: Cls->new( bigness => 7 )Friday, July 6, 12
  • Example: init_arg • Use init_arg => undef to has _genetic_code => ( prevent dependency is => ro, lazy_build => 1, injection init_arg => undef, ); • Use with cautionFriday, July 6, 12
  • Weak References Student Student Student Learns At CourseFriday, July 6, 12
  • Weak References • When an object leaves scope, it’s ref-count decreases • Circular references cause objects to remain in memory • Weak references to the rescueFriday, July 6, 12
  • Weak Ref • When a Course object leaves the last scope - it will package Student; now be deleted use Moose; has name, • When Course object leaves is => ro, required => 1; scope, Moose will has learns_at, automatically clear all is => rw, weak_ref => 1; “learns_at” attributes of students Full Example: https://gist.github.com/3031636Friday, July 6, 12
  • Triggers• Called when attribute value has size => ( is set is => rw, trigger => &_size_set, );• Called when set from new or explicitly sub _size_set { my ( $self, $size, $old_size ) = @_; }• Is not called when set from default or builderFriday, July 6, 12
  • Friday, July 6, 12
  • Lab • Improve Students/Course example to use native delegation • Use method modifiers to add custom logicFriday, July 6, 12
  • Meta MooseFriday, July 6, 12
  • 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 MooseFriday, July 6, 12
  • MOP Parts • The Class protocol • The Attribute protocol • The Method protocol • The Instance protocolFriday, July 6, 12
  • Moose and Class::MOP • Moose is built on top of Class::MOP • Prefixed Moose::Meta (for example Moose::Meta::Class) • Get with $self->metaFriday, July 6, 12
  • 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
  • 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
  • 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 checkingFriday, July 6, 12
  • 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
  • Class Modification • $meta->add_attribute • $meta->remove_attribute • $meta->add_method • $meta->remove_method • $meta->make_immutableFriday, July 6, 12
  • 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
  • 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
  • Friday, July 6, 12
  • Moose Types Customizable Type SystemFriday, July 6, 12
  • 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 detectionFriday, July 6, 12
  • Stock Types • Bool, Maybe[‘a], Str, Num, Int, ClassName, RoleName • Ref, ScalarRef[‘a], ArrayRef[‘a], HashRef[‘a], CodeRef • RegexpRef, GlobRef, FileHandle • ObjectFriday, July 6, 12
  • 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 itFriday, July 6, 12
  • 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
  • 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 anonymousFriday, July 6, 12
  • 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
  • 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
  • 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 arrayFriday, July 6, 12
  • Subtypes • Provide ‘as’ to specify base type subtype NaturalLessThanTen, as Natural, where { $_ < 10 }, • Provide ‘where’ to add message { constraint on the base type "This number ($_) is not less than ten!" }; • Provide your own error message with ‘message’Friday, July 6, 12
  • Subtypes Do’s • Define all your subtype in a single module for code reuse. Use that module from every Moose classFriday, July 6, 12
  • Subtypes Do’s • Prefer namespaced subtypes: ZombieApocalipse::Human::EyeColor is better than EyeColor • Zombies may have different eye color ...Friday, July 6, 12
  • Type Coercion Proceed With CautionFriday, July 6, 12
  • Type Coercion • Automatically convert invalid data to valid • Int ------> ArrayRef[Int] • Str ------> Person • High risk - an invalid value could coerce thus skipping type validationFriday, July 6, 12
  • 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
  • Coercion Don’ts • Don’t add coercion on Moose’s subtypes (unfortunately it’ll work) • Generally, try to avoid coercionsFriday, July 6, 12
  • Friday, July 6, 12
  • Subtypes Lab • Define a new subtype for hex numbers (numbers of the format 0x22) • Add a coercion from HexNum to IntFriday, July 6, 12
  • MooseX More Than MooseFriday, July 6, 12
  • 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 functionalityFriday, July 6, 12
  • Useful MooseX • MooseX::StrictConstructor • MooseX::MultiMethods • MooseX::Singleton • MooseX::HasDefaults • MooseX::Declare • MooseX::APIRole • MooseX::FollowPBP • MooseX::Privacy • MooseX::SingleArgFriday, July 6, 12
  • Simple eXtensions • MooseX::StrictConstructor • MooseX::Singleton • MooseX::FollowPBP • MooseX::SingleArg • MooseX::HasDefaults • MooseX::PrivacyFriday, July 6, 12
  • MooseX::StrictConstructor package Contact; use Moose; use MooseX::StrictConstructor; has email, is => ro; has name, is => ro; • Throw exception if constructor was passed an package main; unexpected argument # Throw an exception Contact->new( name => Bob, emial => bob@gmail.com);Friday, July 6, 12
  • MooseX::Singleton package App; use MooseX::Singleton; package main; • Create only one instance of a class {     my $app = App->instance; } • Has initialization method to pass arguments if needed {     # same one     my $app = App->instance; }Friday, July 6, 12
  • MooseX::FollowPBP • Use set_x and get_x as default reader and writer • SEE ALSO: Perl::CriticFriday, July 6, 12
  • MooseX::SingleArg use v5.14; package Contact; use Moose; use MooseX::SingleArg; • Easily create single arg single_arg name; constructor (without has name, is => ro; wrapping BUILDARGS) package main; my $c = Contact->new(Mike); say $c->name;Friday, July 6, 12
  • MooseX::HasDefaults • Automatically use: use v5.14; is => ‘ro’ package Point; use Moose; use MooseX::HasDefaults::RO; or: has [x, y, z]; is => ‘rw’Friday, July 6, 12
  • MooseX::Privacy use MooseX::Privacy; • Restrict visibility of methods has config => (     is => rw, • private can only be called     isa => Some::Config, from within the class     traits ); => [qw/Private/], • protected can only be private_method foo => sub {     return 23; called from within the class }; or any of its subclasses protected_method bar => sub {     return 42; • Doesn’t work for roles };Friday, July 6, 12
  • Heavy Lifting • Logging: Log4perl • MooseX::APIRole • MooseX::Declare • MooseX::MultiMethodsFriday, July 6, 12
  • 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 log4jFriday, July 6, 12
  • 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 applicationsFriday, July 6, 12
  • Log4perl and Moose package MyApp; • Use use Moose; MooseX::Log:: with MooseX::Log::Log4perl; Log4perl role sub go { in your class     my $self = shift;     $self->log->debug(Starting method go); • New     $self->log->info(Go go go); attributes: log     $self->log(IO)->info(reading data); and logger }Friday, July 6, 12
  • 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 dataFriday, July 6, 12
  • Log4perl Configuration log4perl.logger = DEBUG, Screen, Logfile log4perl.appender.Screen = Log::Log4perl::Appender::Screen log4perl.appender.Screen.layout = PatternLayout log4perl.appender.Screen.layout.ConversionPattern= [%r] %F %l %c - %m%n log4perl.appender.Logfile = Log::Log4perl::Appender::File log4perl.appender.Logfile.filename = my.log log4perl.appender.Logfile.layout = PatternLayout log4perl.appender.Logfile.layout.ConversionPattern = [%d] %F %l %c - %m%nFriday, July 6, 12
  • Log4perl Initialization package main; • Load configuration file on use Log::Log4perl; startup with: Log::Log4perl::init(log.conf); Log::Log4perl::init(filename)Friday, July 6, 12
  • Log4perl Docs • Usage: perldoc Log::Log4perl • Conversion Patterns Layout: http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/ PatternLayout.htmlFriday, July 6, 12
  • MooseX::APIRole package Logger; use Moose; • Automatically create a role use MooseX::APIRole; out of a class sub info { } sub error { } • all subroutines become make_api_role Logger::API; ‘requires’ package Test; use Moose; • Easy to use and very # Fails - Test does not implement powerful # required methods with Logger::API;Friday, July 6, 12
  • MooseX::Declare • Use modern OO syntax for your moose objects • ‘class’ keywordsdeclares a class. Inside, MooseX::Method::Signatures is in effect. • ‘role’ keyword declares a roleFriday, July 6, 12
  • 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
  • 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 moreFriday, July 6, 12
  • MooseX::MultiMethods • Allow multi methods dispatcher based on input arguments • Define multiple handlers instead of long if-else blocksFriday, July 6, 12
  • 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 Rock print $game->play(Paper->new, Rock->new);Friday, July 6, 12
  • Friday, July 6, 12
  • Thanks For Listening • Ynon Perek • ynonperek@yahoo.com • ynonperek.comFriday, July 6, 12