Advanced Perl Moose

82fe3950bdbb0b1048e870fa04c89cfd?s=47 ynonperek
July 06, 2012
2.2k

Advanced Perl Moose

Licensed under Creative Common Non Commercial:
http://creativecommons.org/licenses/by-nc/2.5/

82fe3950bdbb0b1048e870fa04c89cfd?s=128

ynonperek

July 06, 2012
Tweet

Transcript

  1. Ynon Perek ynonperek@yahoo.com http://ynonperek.com Moose Workshop Friday, July 6, 12

  2. Agenda • Moose Overview • Classes • Roles • Attributes

    • Meta Object System • Type System • Moose Extensions • Design Patterns Friday, July 6, 12
  3. Assumptions • You know how to write a Moose classes

    • You know how to define methods and what $self means Friday, July 6, 12
  4. Moose Overview • Developed by Stevan Little (on the right)

    • Started 2006 • Goal: Change the world Friday, July 6, 12
  5. Moose Features • From perl to OO • No boilerplate

    code • Optional type constraints • Inheritance and Mixins • Design Patterns Friday, July 6, 12
  6. Organizations Using Moose • Cisco • IMDb • Infinity Interactive

    • MusicBrainz • Symantec • And others: http://moose.iinteractive.com/ about.html#organizations Friday, July 6, 12
  7. Moose Alternatives • Mouse • Moo • Mo • Class::Builder

    Friday, July 6, 12
  8. Moose HELP • IRC: irc://irc.perl.org/#moose • Mailing List: mailto:moose- subscribe@perl.org

    • Youtube: search for “perl moose” Friday, July 6, 12
  9. Moose Classes Friday, July 6, 12

  10. 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
  11. Moose::Object • new ( %params ) • BUILDARGS ( %params

    ) • DESTROY • does( $role_name ) • DOES( $class_or_role_name ) • dump( $maxdepth ) Friday, July 6, 12
  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 dog's 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
  13. Class Construction • new method is automatically generated. • Takes

    parameters hash or hash ref package main; # Pass a hash ref to prevent copying my $enterprise = Starship->new( { captain => 'James T Kirk', crew => ['Dr. McCoy', 'Scott', 'Lt. Uhura'], }); Friday, July 6, 12
  14. Class Construction • Construction hooks: • BUILD • BUILDARGS •

    attribute builders Friday, July 6, 12
  15. 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
  16. 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
  17. 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
  18. 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 semicolon Friday, July 6, 12
  19. Class Destruction • Moose implemented DESTROY, which will call your

    DEMOLISH • It handles inheritance correctly: demolish child before super Friday, July 6, 12
  20. Class Destruction • When program ends, prints out: Bar::Demolish Foo::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
  21. Construction Destruction Do’s and Don’ts Friday, July 6, 12

  22. Do • Provide reasonable validations with BUILD Friday, July 6,

    12
  23. Do • Use warn( $obj->dump ) for debug Friday, July

    6, 12
  24. Do • Consider namespace::autoclean to remove Moose sugar methods from

    your classes (has, with, etc.) Friday, July 6, 12
  25. Do • Consider using: __PACKAGE__->meta->make_immutable; • To improve performance of

    objects creation • Consider MooseX::AutoImmute Friday, July 6, 12
  26. Don’t • Never override new ( it’ll break stuff down

    the road ) Friday, July 6, 12
  27. Don’t • Don’t use BUILD when attribute builders are sufficient

    Friday, July 6, 12
  28. Don’t • Never call $self->SUPER::BUILD • Moose does that for

    you Friday, July 6, 12
  29. Don’t • Don’t apply a method modifier (before, after, around)

    to BUILD Friday, July 6, 12
  30. Don’t • Don’t write BUILD method for your roles (

    Moose ignores them ) Friday, July 6, 12
  31. 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
  32. 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
  33. 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
  34. 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
  35. 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
  36. 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
  37. 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
  38. Friday, July 6, 12

  39. Moose Roles An alternative to deep hierarchies and base classes

    Friday, July 6, 12
  40. 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
  41. Classes & Roles Alive Think Think Alive Person Computer Chicken

    Friday, July 6, 12
  42. 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
  43. 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
  44. 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
  45. 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
  46. 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
  47. 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
  48. 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
  49. Method Conflict with 'Breakable' => { -alias => { break

    => 'break_bone' }, -excludes => 'break', }, 'Breakdancer' => { -alias => { break => 'break_dance' }, -excludes => 'break', }; Friday, July 6, 12
  50. 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
  51. 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
  52. Friday, July 6, 12

  53. Attributes Friday, July 6, 12

  54. 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
  55. Attribute Options • is, reader, writer • isa • required,

    default, builder • lazy Friday, July 6, 12
  56. 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
  57. 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
  58. 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
  59. 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
  60. 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
  61. Required / Default / Builder • Use required for fields

    that take their value from “outside” • Use default / builder for everything else Friday, July 6, 12
  62. 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
  63. 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
  64. 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
  65. 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
  66. 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
  67. Delegation Contact Email Send Mail Send Mail Phone Call Call

    Friday, July 6, 12
  68. 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
  69. 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
  70. 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
  71. Native Delegation • Native arrays have push, pop, shift, unshift

    and more • Can now use: $q->add_item to 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
  72. Native Delegation • Array functions: Moose::Meta::Attribute::Native::Trait::Array • Hash functions: Moose::Meta::Attribute::Native::Trait::Hash

    Friday, July 6, 12
  73. Friday, July 6, 12

  74. Attributes: Advanced Topics • Predicates & Clearers • Constructor Parameters

    • Weak References • Triggers Friday, July 6, 12
  75. 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 Image No likes yet Image Online 0 Likes. Go find more friends Friday, July 6, 12
  76. 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
  77. 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
  78. 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
  79. 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
  80. 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
  81. Weak References Course Student Student Student Learns At Friday, July

    6, 12
  82. 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
  83. 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/3031636 Friday, July 6, 12
  84. 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
  85. Friday, July 6, 12

  86. Lab • Improve Students/Course example to use native delegation •

    Use method modifiers to add custom logic Friday, July 6, 12
  87. Meta Moose Friday, July 6, 12

  88. 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
  89. MOP Parts • The Class protocol • The Attribute protocol

    • The Method protocol • The Instance protocol Friday, July 6, 12
  90. 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
  91. 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
  92. 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/3032056 Friday, July 6, 12
  93. 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
  94. 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
  95. Class Modification • $meta->add_attribute • $meta->remove_attribute • $meta->add_method • $meta->remove_method

    • $meta->make_immutable Friday, July 6, 12
  96. 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
  97. 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
  98. Friday, July 6, 12

  99. Moose Types Customizable Type System Friday, July 6, 12

  100. 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
  101. 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
  102. 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
  103. 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
  104. 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
  105. 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
  106. 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
  107. 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
  108. 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
  109. 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
  110. Subtypes Do’s • Prefer namespaced subtypes: ZombieApocalipse::Human::EyeColor is better than

    EyeColor • Zombies may have different eye color ... Friday, July 6, 12
  111. Type Coercion Proceed With Caution Friday, July 6, 12

  112. 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
  113. 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
  114. Coercion Don’ts • Don’t add coercion on Moose’s subtypes (unfortunately

    it’ll work) • Generally, try to avoid coercions Friday, July 6, 12
  115. Friday, July 6, 12

  116. 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
  117. MooseX More Than Moose Friday, July 6, 12

  118. 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
  119. Useful MooseX • MooseX::StrictConstructor • MooseX::Singleton • MooseX::Declare • MooseX::FollowPBP

    • MooseX::Privacy • MooseX::SingleArg • MooseX::MultiMethods • MooseX::HasDefaults • MooseX::APIRole Friday, July 6, 12
  120. Simple eXtensions • MooseX::StrictConstructor • MooseX::Singleton • MooseX::FollowPBP • MooseX::SingleArg

    • MooseX::HasDefaults • MooseX::Privacy Friday, July 6, 12
  121. 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 exception Contact->new( name => 'Bob', emial => 'bob@gmail.com'); Friday, July 6, 12
  122. 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
  123. MooseX::FollowPBP • Use set_x and get_x as default reader and

    writer • SEE ALSO: Perl::Critic Friday, July 6, 12
  124. 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
  125. 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
  126. 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
  127. Heavy Lifting • Logging: Log4perl • MooseX::APIRole • MooseX::Declare •

    MooseX::MultiMethods Friday, July 6, 12
  128. 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
  129. 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
  130. 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
  131. 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
  132. 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%n Friday, July 6, 12
  133. 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
  134. 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
  135. 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 methods with 'Logger::API'; Friday, July 6, 12
  136. 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
  137. 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
  138. 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
  139. MooseX::MultiMethods • Allow multi methods dispatcher based on input arguments

    • Define multiple handlers instead of long if-else blocks Friday, July 6, 12
  140. 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
  141. Friday, July 6, 12

  142. Thanks For Listening • Ynon Perek • ynonperek@yahoo.com • ynonperek.com

    Friday, July 6, 12