Your SlideShare is downloading. ×
0
Moose Workshop                     Ynon Perek                     ynonperek@yahoo.com                     http://ynonperek...
Agenda    • Moose           Overview          • Moose    Extensions    • Classes                           • Design   Patt...
Assumptions    • You   know how to write a         Moose classes    • You   know how to define         methods and what $se...
Moose Overview    • Developed      by Stevan Little         (on the right)    • Started        2006    • Goal: Change     ...
Moose Features    • From            perl to OO    • No             boilerplate code    • Optional            type constrai...
Organizations Using Moose    • Cisco    • IMDb    • Infinity         Interactive    • MusicBrainz    • Symantec    • And   ...
Moose Alternatives    • Mouse    • Moo    • Mo    • Class::BuilderFriday, July 6, 12
Moose HELP    • IRC:           irc://irc.perl.org/#moose    • Mailing           List: mailto:moose-         subscribe@perl...
Moose ClassesFriday, July 6, 12
Moose Classes                            • Import sugar functions:                             extends, has, with, ...    ...
Moose::Object    • new            ( %params )    • BUILDARGS             ( %params )    • DESTROY    • does(           $ro...
Example: Getting Info        package Pet;        use Moose;        has name,        is => ro, isa => Str, default => Lassy...
Class Construction                                    package main; • new    method is automatically   # Pass a hash ref t...
Class Construction    • Construction        hooks:          • BUILD          • BUILDARGS          • attribute   buildersFr...
Class Construction    • BUILD           is called every time a new object is created    • If  inheritance is in effect, pa...
Object State Validation          package Starship;          use Moose;          has captain, is => ro, isa => Str, require...
BUILDARGS    • Used           to manipulate arguments before object creation    • Takes          the arguments hash as inp...
BUILDARGS Example                     package Person;                     use Moose;                     has name, is => r...
Class Destruction    • Moose  implemented DESTROY, which will call your         DEMOLISH    • It       handles inheritance...
Class Destruction                             package Foo;                             use Moose;                         ...
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, ...
Do    • Consider             using:         __PACKAGE__->meta->make_immutable;    • To             improve performance of ...
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;            ...
What Is Printed ?                     package Foo;                     use Moose;                     sub DEMOLISH { warn ...
Method Modifiers    • Alter  code by injecting other code before or after the         modified method    • Can            us...
before                                            package Logger;                                            use Mouse;   ...
around    • around          has two more advantages:          • Can      use return value of original method          • Ca...
around    • First  parameter: original        package AroundExample;                                        use Mouse;    ...
around                                         package User;                                         use Mouse;           ...
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    cons...
Classes & Roles                     Person       Computer      Chicken                     Alive                       Ali...
Roles Example  package Breakable;  use Moose::Role;                                                 package Glass;  has is...
Moose Roles    • Use            Moose::Role to define a role    • Use ‘with’ to         consume a role    • Inside         ...
Partial Implementation    • Use ‘requires’ in         a role to force your consumer to define a         method    • Useful ...
Partial Implementation        package MultipleFileUploader;        use Moose::Role;        requires upload_file;        su...
Method Conflicts    • Consuming             two roles with the same method names results in         a conflict    • Class   ...
Method Conflicts                     package R1;          package Test;                     use Moose::Role;     use Moose;...
Method Conflict    • Can    use -alias to make a copy of a role’s method by         another name    • Can            use -e...
Method Conflict                     with Breakable => {                          -alias    => { break => break_bone },     ...
Dynamic Roles    • Roles          can be added to instances after creation    • Usage: debug    tracing on specific obejct,...
Lab    • Implement     a Comparable role which requires a single method:         compare($other) - returns -1 if $other is...
Friday, July 6, 12
AttributesFriday, July 6, 12
Moose Attributes    • An             attribute is a property that every member of a class has    • Some             attrib...
Attribute Options    • is, reader, writer    • isa    • required, default, builder    • lazyFriday, July 6, 12
Readers & Writers                                   package Product;                                   use Moose;    • Use...
Isa    • Use            isa to force a type constraint    • Available Types include: Bool, Str, Num, Int, ScalarRef, Array...
Isa          package Store;          use Moose;          use Client;          use Product;          has owner, is => ro, i...
Subtypes    • Use            subtypes to easily define new constraints:                     use Moose::Util::TypeConstraint...
Enumerations    • Use            enum function to declare an enum subtype    • An             enum takes a single value fr...
Required / Default / Builder    • Use            required for fields that take their value from “outside”    • Use         ...
Builder                                        package Person;                                        use Moose;          ...
lazy                                                  package Person;                                                  use...
Dependency Injection    •A     technique used in testing to build more testable versions of         your classes    • If  ...
Lab    • Implement      a Logger class with one method: log. In the ctor,         logger can take a file name    • If  no a...
Delegation    •A     relationship between classes. A class attribute is an object of         a different class    • Can   ...
Delegation               Send Mail             Send Mail                           Contact               Email            ...
Delegation                                          package Contact;                                          use Moose;  ...
Delegate    • Another     option is to      has uri => (                                       is      => ro,         dele...
Native Delegation    • Give   your object “native” feel by using standard data type         methods    • Currently        ...
Native Delegation                                        has q => (                                            is => ro,  ...
Native Delegation    • Array          functions:         Moose::Meta::Attribute::Native::Trait::Array    • Hash   function...
Friday, July 6, 12
Attributes: Advanced Topics    • Predicates         & Clearers    • Constructor          Parameters    • Weak            R...
Predicates & Clearers    • User    can upload photos,            Uploading Image         other users can “like”           ...
Predicates & Clearers                                       package Photo;                                       use Moose...
Predicates & Clearers                     sub like {                         my $self = shift;                         die...
Constructor Parameters    • Sometimes     the name of the attribute is not the same as the         name of the constructor...
Example: init_arg    • Use    to modify constructor         parameter name                                         has big...
Example: init_arg    • Use     init_arg => undef to     has _genetic_code => (         prevent dependency                i...
Weak References                                   Student       Student   Student                                         ...
Weak References    • When           an object leaves scope, it’s ref-count decreases    • Circular        references cause...
Weak Ref    • When       a Course object         leaves the last scope - it will                                          ...
Triggers• Called             when attribute value   has size => (    is set                                     is      =>...
Friday, July 6, 12
Lab    • Improve           Students/Course example to use native delegation    • Use            method modifiers to add cus...
Meta MooseFriday, July 6, 12
What is MOP    • An     abstraction to build abstractions - or simply put - an API to         build an object system    • ...
MOP Parts    • The            Class protocol    • The Attribute           protocol    • The            Method protocol    ...
Moose and Class::MOP    • Moose            is built on top of Class::MOP    • Prefixed            Moose::Meta (for example ...
What Meta Can Do For You    • Class          and Object Introspection    • Modify     objects and classes dynamically (add...
Object Introspection         package main;         my $z = Zombie->new;         for my $attr ( $z->meta->get_all_attribute...
Object Introspection    • All            meta methods listed under:         Class::MOP::Class and Moose::META::Class    • ...
Validate Type Constraints    • Use    $self->meta->get_attribtue(attr)->type_constraint to get         meta object of type...
Class Modification    • $meta->add_attribute    • $meta->remove_attribute    • $meta->add_method    • $meta->remove_method ...
Moose::Util    •A      bundle of useful functions that take away some of the pain         of working with meta    • Start ...
Moose::Util    • find_meta(       $class_or_obj )    • does_role(      $class_or_obj, $role )    • apply_all_roles(    $app...
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 ...
Stock Types    • Bool, Maybe[‘a], Str, Num, Int, ClassName, RoleName    • Ref, ScalarRef[‘a], ArrayRef[‘a], HashRef[‘a], C...
Type Registry    •A     type is an instance of         Moose::Meta::TypeConstraint    • All  types are stored in the type ...
Example: Print All Constraints         use v5.14;         use Data::Dumper;         use Moose::Util::TypeConstraints;     ...
Extending The Type System    • Every          Moose object is a new type    • There          are also helper methods to cr...
Named Subtypes: enum              use v5.14;              package Person::Types;              use Moose::Util::TypeConstra...
Anonymous Subtypes: enum                      use v5.14;                      package Person;                      use Moo...
More Subtypes    • subtype(       %opts ) - Create a new subtype    • role_type ‘barks’, {   role => ‘Some::Library::Role:...
Subtypes    • Provide ‘as’ to   specify base         type                          subtype NaturalLessThanTen,            ...
Subtypes Do’s    • Define     all your subtype in a single module for code reuse. Use         that module from every Moose ...
Subtypes Do’s    • Prefer  namespaced subtypes:         ZombieApocalipse::Human::EyeColor is better than         EyeColor ...
Type Coercion                      Proceed With CautionFriday, July 6, 12
Type Coercion    • Automatically             convert invalid data to valid    • Int            ------> ArrayRef[Int]    • ...
Type Coercion        use v5.14;        package Student;        use Moose;        use Moose::Util::TypeConstraints;        ...
Coercion Don’ts    • Don’t    add coercion on Moose’s subtypes         (unfortunately it’ll work)    • Generally, try   to...
Friday, July 6, 12
Subtypes Lab    • Define     a new subtype for hex numbers (numbers of the         format 0x22)    • Add            a coerc...
MooseX                     More Than MooseFriday, July 6, 12
eXtending Moose    • Moose          is (relatively) easy to change and extend    • Writing         extensions can take som...
Useful MooseX  • MooseX::StrictConstructor   • MooseX::MultiMethods  • MooseX::Singleton           • MooseX::HasDefaults  ...
Simple eXtensions    • MooseX::StrictConstructor    • MooseX::Singleton    • MooseX::FollowPBP    • MooseX::SingleArg    •...
MooseX::StrictConstructor                                     package Contact;                                     use Moo...
MooseX::Singleton                                            package App;                                            use M...
MooseX::FollowPBP    • Use    set_x and get_x as         default reader and writer    • SEE ALSO: Perl::CriticFriday, July...
MooseX::SingleArg                                   use v5.14;                                   package Contact;         ...
MooseX::HasDefaults    • Automatically    use:                                use v5.14;         is => ‘ro’             pa...
MooseX::Privacy                                             use MooseX::Privacy;    • Restrict       visibility of methods...
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 contr...
Log4perl alternatives    • print/warn     debug messages: Too simple for real apps    • roll-your-own: Too    much work......
Log4perl and Moose                           package MyApp;    • Use                  use Moose;         MooseX::Log::    ...
Log4perl Output    • Completely         customizable    • Output         log to: Screen, File, Socket, DBI, and more    • ...
Log4perl Configuration           log4perl.logger = DEBUG, Screen, Logfile           log4perl.appender.Screen = Log::Log4per...
Log4perl Initialization                                        package main;    • Load     configuration file on      use Lo...
Log4perl Docs    • Usage:         perldoc Log::Log4perl    • Conversion      Patterns Layout:         http://logging.apach...
MooseX::APIRole                                          package Logger;                                          use Moos...
MooseX::Declare    • Use            modern OO syntax for your moose objects    • ‘class’ keywordsdeclares a class. Inside,...
MooseX::Declare    use MooseX::Declare;    class BankAccount {        has balance => ( isa => Num, is => rw, default => 0 ...
MooseX::Declare    • Still          experimental, API could change    • Inside   a method $self is already defined for you,...
MooseX::MultiMethods    • Allow          multi methods dispatcher based on input arguments    • Define          multiple ha...
MooseX::MultiMethods              package Paper;    use Moose;              package Scissors; use Moose;              pack...
Friday, July 6, 12
Thanks For Listening    • Ynon           Perek    • ynonperek@yahoo.com    • ynonperek.comFriday, July 6, 12
Upcoming SlideShare
Loading in...5
×

Moose workshop

1,617

Published on

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

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,617
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
30
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Transcript of "Moose workshop"

  1. 1. Moose Workshop Ynon Perek ynonperek@yahoo.com http://ynonperek.comFriday, July 6, 12
  2. 2. Agenda • Moose Overview • Moose Extensions • Classes • Design Patterns • Roles • Attributes • Meta Object System • Type SystemFriday, July 6, 12
  3. 3. Assumptions • You know how to write a Moose classes • You know how to define methods and what $self meansFriday, July 6, 12
  4. 4. Moose Overview • Developed by Stevan Little (on the right) • Started 2006 • Goal: Change the worldFriday, July 6, 12
  5. 5. Moose Features • From perl to OO • No boilerplate code • Optional type constraints • Inheritance and Mixins • Design PatternsFriday, July 6, 12
  6. 6. Organizations Using Moose • Cisco • IMDb • Infinity Interactive • MusicBrainz • Symantec • And others: http://moose.iinteractive.com/ about.html#organizationsFriday, July 6, 12
  7. 7. Moose Alternatives • Mouse • Moo • Mo • Class::BuilderFriday, July 6, 12
  8. 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. 9. Moose ClassesFriday, July 6, 12
  10. 10. 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
  11. 11. Moose::Object • new ( %params ) • BUILDARGS ( %params ) • DESTROY • does( $role_name ) • DOES( $class_or_role_name ) • dump( $maxdepth )Friday, July 6, 12
  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 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
  13. 13. 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
  14. 14. Class Construction • Construction hooks: • BUILD • BUILDARGS • attribute buildersFriday, July 6, 12
  15. 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 creationFriday, July 6, 12
  16. 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. 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 ctorFriday, July 6, 12
  18. 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 semicolonFriday, July 6, 12
  19. 19. Class Destruction • Moose implemented DESTROY, which will call your DEMOLISH • It handles inheritance correctly: demolish child before superFriday, July 6, 12
  20. 20. 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
  21. 21. Construction Destruction Do’s and Don’tsFriday, July 6, 12
  22. 22. Do • Provide reasonable validations with BUILDFriday, July 6, 12
  23. 23. Do • Use warn( $obj->dump ) for debugFriday, July 6, 12
  24. 24. Do • Consider namespace::autoclean to remove Moose sugar methods from your classes (has, with, etc.)Friday, July 6, 12
  25. 25. Do • Consider using: __PACKAGE__->meta->make_immutable; • To improve performance of objects creation • Consider MooseX::AutoImmuteFriday, July 6, 12
  26. 26. Don’t • Never override new ( it’ll break stuff down the road )Friday, July 6, 12
  27. 27. Don’t • Don’t use BUILD when attribute builders are sufficientFriday, July 6, 12
  28. 28. Don’t • Never call $self->SUPER::BUILD • Moose does that for youFriday, July 6, 12
  29. 29. Don’t • Don’t apply a method modifier (before, after, around) to BUILDFriday, July 6, 12
  30. 30. Don’t • Don’t write BUILD method for your roles ( Moose ignores them )Friday, July 6, 12
  31. 31. 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
  32. 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. 33. 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
  34. 34. 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
  35. 35. 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
  36. 36. 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
  37. 37. 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
  38. 38. Friday, July 6, 12
  39. 39. Moose Roles An alternative to deep hierarchies and base classesFriday, July 6, 12
  40. 40. 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
  41. 41. Classes & Roles Person Computer Chicken Alive Alive Think ThinkFriday, July 6, 12
  42. 42. 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
  43. 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 roleFriday, July 6, 12
  44. 44. 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
  45. 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. 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 namespaceFriday, July 6, 12
  47. 47. 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
  48. 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 conflictFriday, July 6, 12
  49. 49. Method Conflict with Breakable => { -alias => { break => break_bone }, -excludes => break, }, Breakdancer => { -alias => { break => break_dance }, -excludes => break, };Friday, July 6, 12
  50. 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. 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 roleFriday, July 6, 12
  52. 52. Friday, July 6, 12
  53. 53. AttributesFriday, July 6, 12
  54. 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. 55. Attribute Options • is, reader, writer • isa • required, default, builder • lazyFriday, July 6, 12
  56. 56. 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
  57. 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 yourselfFriday, July 6, 12
  58. 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. 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. 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. 61. Required / Default / Builder • Use required for fields that take their value from “outside” • Use default / builder for everything elseFriday, July 6, 12
  62. 62. 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
  63. 63. 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
  64. 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 winsFriday, July 6, 12
  65. 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/3029901Friday, July 6, 12
  66. 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 methodsFriday, July 6, 12
  67. 67. Delegation Send Mail Send Mail Contact Email Call Call PhoneFriday, July 6, 12
  68. 68. 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
  69. 69. 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
  70. 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 typeFriday, July 6, 12
  71. 71. 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
  72. 72. Native Delegation • Array functions: Moose::Meta::Attribute::Native::Trait::Array • Hash functions: Moose::Meta::Attribute::Native::Trait::HashFriday, July 6, 12
  73. 73. Friday, July 6, 12
  74. 74. Attributes: Advanced Topics • Predicates & Clearers • Constructor Parameters • Weak References • TriggersFriday, July 6, 12
  75. 75. 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
  76. 76. 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
  77. 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. 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 injectionFriday, July 6, 12
  79. 79. 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
  80. 80. 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
  81. 81. Weak References Student Student Student Learns At CourseFriday, July 6, 12
  82. 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 rescueFriday, July 6, 12
  83. 83. 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
  84. 84. 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
  85. 85. Friday, July 6, 12
  86. 86. Lab • Improve Students/Course example to use native delegation • Use method modifiers to add custom logicFriday, July 6, 12
  87. 87. Meta MooseFriday, July 6, 12
  88. 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 MooseFriday, July 6, 12
  89. 89. MOP Parts • The Class protocol • The Attribute protocol • The Method protocol • The Instance protocolFriday, July 6, 12
  90. 90. 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
  91. 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. 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/3032056Friday, July 6, 12
  93. 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 checkingFriday, July 6, 12
  94. 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. 95. Class Modification • $meta->add_attribute • $meta->remove_attribute • $meta->add_method • $meta->remove_method • $meta->make_immutableFriday, July 6, 12
  96. 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. 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. 98. Friday, July 6, 12
  99. 99. Moose Types Customizable Type SystemFriday, July 6, 12
  100. 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 detectionFriday, July 6, 12
  101. 101. 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
  102. 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 itFriday, July 6, 12
  103. 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. 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 anonymousFriday, July 6, 12
  105. 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. 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. 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 arrayFriday, July 6, 12
  108. 108. 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
  109. 109. Subtypes Do’s • Define all your subtype in a single module for code reuse. Use that module from every Moose classFriday, July 6, 12
  110. 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. 111. Type Coercion Proceed With CautionFriday, July 6, 12
  112. 112. 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
  113. 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. 114. Coercion Don’ts • Don’t add coercion on Moose’s subtypes (unfortunately it’ll work) • Generally, try to avoid coercionsFriday, July 6, 12
  115. 115. Friday, July 6, 12
  116. 116. Subtypes Lab • Define a new subtype for hex numbers (numbers of the format 0x22) • Add a coercion from HexNum to IntFriday, July 6, 12
  117. 117. MooseX More Than MooseFriday, July 6, 12
  118. 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 functionalityFriday, July 6, 12
  119. 119. Useful MooseX • MooseX::StrictConstructor • MooseX::MultiMethods • MooseX::Singleton • MooseX::HasDefaults • MooseX::Declare • MooseX::APIRole • MooseX::FollowPBP • MooseX::Privacy • MooseX::SingleArgFriday, July 6, 12
  120. 120. Simple eXtensions • MooseX::StrictConstructor • MooseX::Singleton • MooseX::FollowPBP • MooseX::SingleArg • MooseX::HasDefaults • MooseX::PrivacyFriday, July 6, 12
  121. 121. 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
  122. 122. 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
  123. 123. MooseX::FollowPBP • Use set_x and get_x as default reader and writer • SEE ALSO: Perl::CriticFriday, July 6, 12
  124. 124. 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
  125. 125. 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
  126. 126. 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
  127. 127. Heavy Lifting • Logging: Log4perl • MooseX::APIRole • MooseX::Declare • MooseX::MultiMethodsFriday, July 6, 12
  128. 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 log4jFriday, July 6, 12
  129. 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 applicationsFriday, July 6, 12
  130. 130. 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
  131. 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 dataFriday, July 6, 12
  132. 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%nFriday, July 6, 12
  133. 133. 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
  134. 134. 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
  135. 135. 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
  136. 136. 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
  137. 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. 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 moreFriday, July 6, 12
  139. 139. MooseX::MultiMethods • Allow multi methods dispatcher based on input arguments • Define multiple handlers instead of long if-else blocksFriday, July 6, 12
  140. 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. 141. Friday, July 6, 12
  142. 142. Thanks For Listening • Ynon Perek • ynonperek@yahoo.com • ynonperek.comFriday, July 6, 12
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×