Your SlideShare is downloading. ×
0
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Moose workshop
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Moose workshop

1,600

Published on

Object Oriented got a lot easier since Moose came around. …

Object Oriented got a lot easier since Moose came around.

This keynote is a one-day advanced Moose workshop covering (almost) everything Moose has to offer perl developers

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

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

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  1. Moose Workshop Ynon Perek ynonperek@yahoo.com http://ynonperek.comFriday, July 6, 12
  2. Agenda • Moose Overview • Moose Extensions • Classes • Design Patterns • Roles • Attributes • Meta Object System • Type SystemFriday, July 6, 12
  3. Assumptions • You know how to write a Moose classes • You know how to define methods and what $self meansFriday, July 6, 12
  4. Moose Overview • Developed by Stevan Little (on the right) • Started 2006 • Goal: Change the worldFriday, July 6, 12
  5. Moose Features • From perl to OO • No boilerplate code • Optional type constraints • Inheritance and Mixins • Design PatternsFriday, July 6, 12
  6. Organizations Using Moose • Cisco • IMDb • Infinity Interactive • MusicBrainz • Symantec • And others: http://moose.iinteractive.com/ about.html#organizationsFriday, July 6, 12
  7. Moose Alternatives • Mouse • Moo • Mo • Class::BuilderFriday, 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 ClassesFriday, July 6, 12
  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. 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 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. 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. Class Construction • Construction hooks: • BUILD • BUILDARGS • attribute buildersFriday, 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 creationFriday, 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 ctorFriday, 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 semicolonFriday, July 6, 12
  19. Class Destruction • Moose implemented DESTROY, which will call your DEMOLISH • It handles inheritance correctly: demolish child before superFriday, July 6, 12
  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. Construction Destruction Do’s and Don’tsFriday, July 6, 12
  22. Do • Provide reasonable validations with BUILDFriday, July 6, 12
  23. Do • Use warn( $obj->dump ) for debugFriday, 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::AutoImmuteFriday, 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 sufficientFriday, July 6, 12
  28. Don’t • Never call $self->SUPER::BUILD • Moose does that for youFriday, July 6, 12
  29. Don’t • Don’t apply a method modifier (before, after, around) to BUILDFriday, July 6, 12
  30. Don’t • Don’t write BUILD method for your roles ( Moose ignores them )Friday, July 6, 12
  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. 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 itselfFriday, July 6, 12
  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. 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. 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. 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. Friday, July 6, 12
  39. Moose Roles An alternative to deep hierarchies and base classesFriday, 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 classFriday, July 6, 12
  41. Classes & Roles Person Computer Chicken Alive Alive Think ThinkFriday, July 6, 12
  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. 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. 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. 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 namespaceFriday, July 6, 12
  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. 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. 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 roleFriday, July 6, 12
  52. Friday, July 6, 12
  53. AttributesFriday, 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 • lazyFriday, July 6, 12
  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. 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. 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 elseFriday, July 6, 12
  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. 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. 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. 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. 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. Delegation Send Mail Send Mail Contact Email Call Call PhoneFriday, July 6, 12
  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. 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. 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. 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. Native Delegation • Array functions: Moose::Meta::Attribute::Native::Trait::Array • Hash functions: Moose::Meta::Attribute::Native::Trait::HashFriday, July 6, 12
  73. Friday, July 6, 12
  74. Attributes: Advanced Topics • Predicates & Clearers • Constructor Parameters • Weak References • TriggersFriday, July 6, 12
  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. 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. 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 injectionFriday, July 6, 12
  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. 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. Weak References Student Student Student Learns At CourseFriday, 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 rescueFriday, July 6, 12
  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. 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. Friday, July 6, 12
  86. Lab • Improve Students/Course example to use native delegation • Use method modifiers to add custom logicFriday, July 6, 12
  87. Meta MooseFriday, 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 MooseFriday, July 6, 12
  89. MOP Parts • The Class protocol • The Attribute protocol • The Method protocol • The Instance protocolFriday, 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->metaFriday, 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/3032056Friday, 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 checkingFriday, 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_immutableFriday, 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 SystemFriday, 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 detectionFriday, 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 • ObjectFriday, 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 itFriday, 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 anonymousFriday, 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 arrayFriday, July 6, 12
  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. 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. 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 CautionFriday, 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 validationFriday, 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 coercionsFriday, 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 IntFriday, July 6, 12
  117. MooseX More Than MooseFriday, 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 functionalityFriday, July 6, 12
  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. Simple eXtensions • MooseX::StrictConstructor • MooseX::Singleton • MooseX::FollowPBP • MooseX::SingleArg • MooseX::HasDefaults • MooseX::PrivacyFriday, July 6, 12
  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. 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. MooseX::FollowPBP • Use set_x and get_x as default reader and writer • SEE ALSO: Perl::CriticFriday, July 6, 12
  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. 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. 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. Heavy Lifting • Logging: Log4perl • MooseX::APIRole • MooseX::Declare • MooseX::MultiMethodsFriday, 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 log4jFriday, 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 applicationsFriday, July 6, 12
  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. 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. 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. 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. 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. 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. 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. 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 moreFriday, July 6, 12
  139. MooseX::MultiMethods • Allow multi methods dispatcher based on input arguments • Define multiple handlers instead of long if-else blocksFriday, 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.comFriday, July 6, 12

×