Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Advanced Perl Moose

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for ynonperek ynonperek
July 06, 2012
2.7k

Advanced Perl Moose

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

Avatar for ynonperek

ynonperek

July 06, 2012
Tweet

Transcript

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

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

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

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

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

    • MusicBrainz • Symantec • And others: http://moose.iinteractive.com/ about.html#organizations Friday, July 6, 12
  6. 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
  7. Moose::Object • new ( %params ) • BUILDARGS ( %params

    ) • DESTROY • does( $role_name ) • DOES( $class_or_role_name ) • dump( $maxdepth ) Friday, July 6, 12
  8. 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
  9. 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
  10. 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
  11. 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
  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 ctor Friday, July 6, 12
  13. 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
  14. Class Destruction • Moose implemented DESTROY, which will call your

    DEMOLISH • It handles inheritance correctly: demolish child before super Friday, July 6, 12
  15. 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
  16. Do • Consider namespace::autoclean to remove Moose sugar methods from

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

    objects creation • Consider MooseX::AutoImmute Friday, July 6, 12
  18. Don’t • Don’t write BUILD method for your roles (

    Moose ignores them ) Friday, July 6, 12
  19. 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
  20. 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
  21. 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
  22. 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
  23. 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
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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
  29. 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
  30. 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
  31. 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
  32. 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
  33. 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
  34. Method Conflict with 'Breakable' => { -alias => { break

    => 'break_bone' }, -excludes => 'break', }, 'Breakdancer' => { -alias => { break => 'break_dance' }, -excludes => 'break', }; Friday, July 6, 12
  35. 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
  36. 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
  37. 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
  38. Attribute Options • is, reader, writer • isa • required,

    default, builder • lazy Friday, July 6, 12
  39. 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
  40. 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
  41. 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
  42. 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
  43. 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
  44. Required / Default / Builder • Use required for fields

    that take their value from “outside” • Use default / builder for everything else Friday, July 6, 12
  45. 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
  46. 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
  47. 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
  48. 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
  49. 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
  50. 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
  51. 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
  52. 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
  53. 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
  54. Attributes: Advanced Topics • Predicates & Clearers • Constructor Parameters

    • Weak References • Triggers Friday, July 6, 12
  55. 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
  56. 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
  57. 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
  58. 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
  59. 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
  60. 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
  61. 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
  62. 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
  63. 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
  64. Lab • Improve Students/Course example to use native delegation •

    Use method modifiers to add custom logic Friday, July 6, 12
  65. 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
  66. MOP Parts • The Class protocol • The Attribute protocol

    • The Method protocol • The Instance protocol Friday, July 6, 12
  67. 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
  68. 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
  69. 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
  70. 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
  71. 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
  72. 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
  73. 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
  74. 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
  75. 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
  76. 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
  77. 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
  78. 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
  79. 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
  80. 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
  81. 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
  82. 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
  83. 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
  84. Subtypes Do’s • Prefer namespaced subtypes: ZombieApocalipse::Human::EyeColor is better than

    EyeColor • Zombies may have different eye color ... Friday, July 6, 12
  85. 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
  86. 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
  87. Coercion Don’ts • Don’t add coercion on Moose’s subtypes (unfortunately

    it’ll work) • Generally, try to avoid coercions Friday, July 6, 12
  88. 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
  89. 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
  90. Useful MooseX • MooseX::StrictConstructor • MooseX::Singleton • MooseX::Declare • MooseX::FollowPBP

    • MooseX::Privacy • MooseX::SingleArg • MooseX::MultiMethods • MooseX::HasDefaults • MooseX::APIRole Friday, July 6, 12
  91. 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 => '[email protected]'); Friday, July 6, 12
  92. 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
  93. MooseX::FollowPBP • Use set_x and get_x as default reader and

    writer • SEE ALSO: Perl::Critic Friday, July 6, 12
  94. 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
  95. 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
  96. 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
  97. 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
  98. 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
  99. 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
  100. 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
  101. 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
  102. 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
  103. 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
  104. 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
  105. 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
  106. 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
  107. 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
  108. MooseX::MultiMethods • Allow multi methods dispatcher based on input arguments

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