Moose - YAPC::NA 2012

1,889 views
1,766 views

Published on

This is the Moose talk I gave at YAPC::NA 2012.

It included a practical example of a Moose objects code, a simple app called Comican. The code is not available online. If you want it, just email me (sawyer ATT cpan DOTT org).

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,889
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
13
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Moose - YAPC::NA 2012

  1. 1. MooseSawyer X
  2. 2. Sawyer Xblogs.perl.org/users/sawyer_xsearch.cpan.org/~xsawyerxmetacpan.org/author/XSAWYERXgithub.com/xsawyerx/„The Dancer guy!“Projects: Dancer, Module::Starter, MetaCPAN::API, MooseX::Role::Loggable, etc.
  3. 3. MooseObject systemMetaclass-basedAdvancedSophisticatedExtensibleProduction-ready
  4. 4. … but why Moose?package Person; package User;use strict; use Email::Valid;use warnings; use Moose; use Moose::Util::TypeConstraints;use Carp qw( confess );use DateTime; extends Person;use DateTime::Format::Natural; subtype Email     => as Strsub new {     => where { Email::Valid­>address($_) }    my $class = shift;     => message { "$_ is not a valid email     my %p = ref $_[0] ? %{ $_[0] } : @_; address" };    exists $p{name} has email_address => (        or confess name is a required attribute;     is       => rw,    $class­>_validate_name( $p{name} );     isa      => Email,     required => 1,    exists $p{birth_date} );        or confess birth_date is a required attribute;    $p{birth_date} = $class­>_coerce_birth_date( $p{birth_date} );    $class­>_validate_birth_date( $p{birth_date} );    $p{shirt_size} = l        unless exists $p{shirt_size}:    $class­>_validate_shirt_size( $p{shirt_size} );    return bless %p, $class;}sub _validate_name {    shift;    my $name = shift;    local $Carp::CarpLevel = $Carp::CarpLevel + 1;    defined $name        or confess name must be a string;}
  5. 5. Get it?
  6. 6. Writing objects in basic Perl 5Create a reference (usually to a hash)Connect it to a package (using „bless“)Provide subroutines that access the hash keysError check the hell out of it
  7. 7. Writing objects in basic Perl 5, e.g.package Dog;use strict; use warnings;sub new { my $class = shift; my $self = bless {}, $class; return $self;}1;
  8. 8. IssuesDefining the same new() concept every timeNo parameters for new() yetWill have to do all error-checking manually
  9. 9. Moosepackage Dog;use Moose;1;
  10. 10. You getuse strict;use warnings;new() methodTo hell with ponies, you get a moose!(roll picture of a moose beating a pony in soccer)
  11. 11. Full affordance accessors (attributes)has name => ( is => rw );„ro“ is available for read-only attributesYou can manually change setter/getter via writer/readerAttributes can have defaultsAttributes can have type constraintsAttributes can have traitsAttributes can be lazy, have builders, clearers, predicates...
  12. 12. Type constraintshas name => ( is => ro, isa => Str );Str, Int, Bool, ArrayRef, HashRef, CodeRef, Regex, ClassesCombine: ArrayRef|HashRef, ArrayRef[Str]Derivatives (Int is a Num)Create your own using subtype, available at Moose::Util::TypeConstraints
  13. 13. MethodsSame as beforesub run { my $self = shift; say qq{I make it a habit only to run when being chased!};}
  14. 14. Inheritance easy as...package Punkuse Moose;extends Person;Multiple inheritance also possible (extends accepts array)package Child;use Moose;extends qw/Father Mother/;
  15. 15. Roles are even betterpackage Punk;use Moose;with qw/Tattoos Piercings Squatter/;Roles are things you do, instead of things you are.
  16. 16. More hooks than a coat rack!package User::WinterAware;use Moose;extends User;before leaving => sub { my $self = shift; $self->cold and $self->take_jacket;};
  17. 17. More hooks than a coat rack!package User::Secure;use Moose;extends User;around login => sub { my $orig = shift; my $self = shift; $self->security_check and $self->$orig(@_);};
  18. 18. More hooks than a coat rack!BeforeAfterAroundInnerAugment
  19. 19. Back to attributes...has set => ( is => rw, isa => Set::Object, default => sub { Set::Object->new }, required => 1, lazy => 1, predicate => has_set, clearer => clear_set,
  20. 20. Attribute options: defaultdefault => kitteh # stringdefault => 3 # numberdefault => sub { {} } # HashRefdefault => sub { [] } # ArrayRefdefault => sub { Object->new } # an Object (if you need a more elaborate sub, use builder)
  21. 21. Attribute options: requiredrequired => 1 # requiredrequired => 0 # not required
  22. 22. Attribute options: lazylazy => 1 # make it lazyClass will not create the slot for this attribute unless itabsolutely has to, defined by whether it is accessed at all.No access? No penalty!Lazy == good
  23. 23. Attribute options: builderbuilder => build_it # subroutine namesub build_it { my $self = shift; # not a problem! return Some::Object->new( $self->more_opts );}
  24. 24. Attribute options: clearerclearer => clear_it # subroutine name# you dont need to create the subroutinesub time_machine { my $self = shift; $self->clear_it; # it never happened :)}
  25. 25. Attribute options: predicatepredicate => has_it # subroutine name# you dont need to create the subroutinesub try_to_do_it { my $self = shift; $self->has_it && $self->do_it();}
  26. 26. Attribute options: lazy_buildlazy_build => 1 # <3# the same as:lazy => 1,builder => _build_it, # privateclearer => clear_it,predicate => has_it,
  27. 27. Example: ComicanA hub for various comics stripsAllow you to fetch comic stripsStandard uniformed interface to add more comicsWell be using: Roles Lazy attributes Overriding attributes options Attribute predicates
  28. 28. Comican comic modules Comican::Comic::Dilber t interface role Comican::Comic::PennyArcadeComican::Comic::xkcd Comican:: Role::Comic main module user Comican.pm
  29. 29. Comican: overallComican.pm is the users interfaceIts a hub for Comican::Comic::* modulesThey are objects that fetch specific comic stripsThey have a common interfaceDefined by Comican::Role::Comic
  30. 30. SHOW ME THE CODE!
  31. 31. /^M(?:o(?:o|[ou]se)?)?$/Moose: standartMouse: subset, uses XS, faster(Any::Moose: use Mouse unless Moose already loaded)Moo: Pure-Perl, subset, blazing fastMo: As little as possible (incl. character count)M: Really as little as possibleHummus (HuMoose): Incompatible chickpeas paste
  32. 32. Thank you.

×