X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=moose-class%2Fslides%2Findex.html;h=adf159fe30bf349b099b01d6b87ecaad19794af6;hb=c030f6e8ffa441ca1cfa386722aa5a44b8c2a99a;hp=e44c60eb157493cf221bf334fec77de3d1a5ed39;hpb=e326acd629d05406fd326f7d306f3bbb1871ccff;p=gitmo%2Fmoose-presentations.git diff --git a/moose-class/slides/index.html b/moose-class/slides/index.html index e44c60e..adf159f 100644 --- a/moose-class/slides/index.html +++ b/moose-class/slides/index.html @@ -52,7 +52,17 @@ img#me05 {top: 43px;left: 36px;}

Introduction to Moose

-

git://git.moose.perl.org/moose-presentations.git

+

Dave Rolsky +

+ +
+

Introduce Yourselves

+ +
@@ -61,7 +71,8 @@ img#me05 {top: 43px;left: 36px;}
@@ -208,7 +219,7 @@ use Moose; @@ -265,7 +276,7 @@ has weight => ( ); # kaboom -Person->new( weight => 'fat' ); +Person->new( weight => 'heavy' );
@@ -290,8 +301,8 @@ has blog_uri => ( handles => { 'blog_host' => 'host' }, ); -$person->blog_host; -# really calls $person->blog_uri->host +$person->blog_host; +# really calls $person->blog_uri->host
@@ -299,7 +310,7 @@ has blog_uri => (
@@ -832,6 +843,16 @@ has last_name => ( ); +
+

More Why Moose?

+ + +
+

Part 1: Moose Classes

@@ -872,8 +893,8 @@ use Moose;

BUILDARGS

@@ -931,11 +952,11 @@ sub BUILD {
Person->new(@_)
-
    +
    1. Calls Person->BUILDARGS(@_) to turn @_ into a hashref
    2. Blesses a reference
    3. Populates attributes based on the hashref from #1
    4. -
    5. Calls $new_object->BUILDALL($constructor_args) +
    6. Calls $new_object->BUILDALL($constructor_args)
      ... which calls all BUILD methods
    7. Returns the object
    @@ -947,6 +968,7 @@ sub BUILD { @@ -956,6 +978,7 @@ sub BUILD { @@ -964,6 +987,8 @@ sub BUILD {
    package Employee;
    @@ -1017,6 +1042,7 @@ extends 'LWP';
    @@ -1044,6 +1070,7 @@ use Moose;
  1. Mostly like $self->SUPER::work(@_)
  2. But cannot change @_!
  3. Binds the parent's method at compile time
  4. +
  5. Parent determined by checking Child->meta()->superclasses()
  6. @@ -1084,8 +1111,7 @@ has first_name => ( is => 'ro' ); my $person = Person->new( first_name => 'Dave' ); -$person->first_name('Stevan'); -print $person->first_name; # Dave +$person->first_name('Stevan'); # dies @@ -1104,7 +1130,7 @@ print $person->first_name; # Dave use Moose; # true -Person->can('extends'); +Person->can('extends'); + + +
    +

    Basic Attributes Summary

    + +
    -

    What is a Method Modifier

    +

    What Are Method Modifiers For?

    @@ -2350,7 +2348,7 @@ after clear_password => sub { $self->$orig( $self->_munge_insert(@_) ); - $new_user->_assign_uri; + $new_user->_assign_uri; return $new_user; }; @@ -2359,7 +2357,7 @@ after clear_password => sub {

    Modifier Order

    @@ -2414,6 +2412,7 @@ around run => sub { @@ -2422,19 +2421,21 @@ around run => sub {

    Augment and Inner

    -
    package Document;
    +  
    package Document;
     
     sub xml { '<doc>' . inner() . '</doc>' }
     
     package Report;
     extends 'Document';
     augment xml =>
    -    sub { title() . inner() . summary() };
    +    sub { my $self = shift;
    +          $self->title() . inner() . $self->summary() };
     
     package TPSReport;
     extends 'Report';
     augment xml =>
    -    sub { tps_xml() . inner() };
    + sub { my $self = shift; + $self->tps_xml() . inner() };
    @@ -2556,11 +2557,11 @@ Item Undef Defined Value - Num - Int - Str - ClassName - RoleName + Str + Num + Int + ClassName + RoleName
    @@ -2570,6 +2571,7 @@ Item
     (Item)
         (Defined)
    +        (Value)
             Ref
                 ScalarRef
                 ArrayRef[`a]
    @@ -2577,7 +2579,7 @@ Item
                 CodeRef
                 RegexpRef
                 GlobRef
    -              FileHandle
    +                FileHandle
                 Object
     
    @@ -2608,6 +2610,7 @@ undef @@ -2708,9 +2711,11 @@ has start_date => (

    Subtype Shortcuts - class_type

    use Moose::Util::TypeConstraints;
    -class_type 'DateTime';
    +class_type 'DateTime';
    -subtype 'DateTime', +
    + +
    subtype     'DateTime',
         as      'Object',
         where   { $_->isa('DateTime') },
         message { ... };
    @@ -2720,10 +2725,12 @@ subtype 'DateTime',

    Subtype Shortcuts - role_type

    use Moose::Util::TypeConstraints;
    -role_type 'Printable';
    +role_type 'Printable';
    -subtype 'Printable', - as 'Object', +
    + +
    subtype 'Printable',
    +    as  'Object',
         where
             { Moose::Util::does_role(
                   $_, 'Printable' ) },
    @@ -2734,9 +2741,11 @@ subtype 'Printable',
       

    Subtype Shortcuts - duck_type

    use Moose::Util::TypeConstraints;
    -duck_type Car => qw( run break_down );
    +duck_type Car => qw( run break_down );
    + +
    -subtype 'Car', +
    subtype 'Car',
         as      'Object',
         where   { all { $_->can($_) }
                   qw( run break_down ) },
    @@ -2747,12 +2756,14 @@ subtype 'Car',
       

    Subtype Shortcuts - enum

    use Moose::Util::TypeConstraints;
    -enum Color => qw( red blue green ) );
    +enum Color => qw( red blue green );
    -my %ok = map { $_ => 1 } +
    + +
    my %ok = map { $_ => 1 }
                  qw( red blue green );
     
    -subtype 'Color'
    +subtype     'Color'
         as      'Str',
         where   { $ok{$_} },
         message { ... };
    @@ -2828,7 +2839,7 @@ coerce 'My::DateTime', via { [ $_ ] };
      -
    • Coerce instead of a union like Int | ArrayRef[Int]
    • +
    • Instead of union - Int | ArrayRef[Int]
    @@ -2853,7 +2864,7 @@ has favorite_numbers => (

    More Droppings

      -
    • Moose::Util::TypeConstraint also needs cleanup
    • +
    • Moose::Util::TypeConstraints also needs cleanup
    package Person;
    @@ -2868,6 +2879,19 @@ no Moose;
     
     
     
    +

    Questions So Far?

    +
    + +
    +

    Exercises

    + +
    # cd exercises
    +# perl bin/prove -lv t/05-types.t
    +
    +Iterate til this passes all its tests
    +
    + +

    Typed Methods (Low-tech)

    package Person;
    @@ -2880,7 +2904,7 @@ sub work {
                 \@_,
                 tasks    =>
                     { isa    => 'ArrayRef[Task]',
    -                  coerce =>1 },
    +                  coerce => 1 },
                 can_rest =>
                     { isa     => 'Bool',
                       default => 0 },
    @@ -2908,7 +2932,7 @@ sub work {
       

    Digression: The Type Registry

      -
    • Types are actually Moose::Meta::TypeConstraint objects
    • +
    • Types are actually Moose::Meta::TypeConstraints objects
    • Stored in an interpreter-global registry mapping names to objects
    @@ -2998,9 +3022,9 @@ coerce ArrayOfInt use MyApp::Types qw( ArrayOfInt ); -has transaction_history => ( - is => 'rw', - isa => ArrayOfInt, +has transaction_history => ( + is => 'rw', + isa => ArrayOfInt, );
    @@ -3010,7 +3034,7 @@ has transaction_history => (
    • Type names are exported functions, catches typos early
    • Types must be pre-declared
    • -
    • Types are stored with namespaces internally, but externally are short
    • +
    • Types are stored with namespaces internally, but you use short names
    • Import existing Moose types as functions from MooseX::Types::Moose
    • Still need string names for things like ArrayRef['Email::Address']
    @@ -3023,7 +3047,7 @@ has transaction_history => (
  7. Catches typos at compile time
  8. Automatic namespacing
  9. One more thing to install and learn
  10. -
  11. Every name gets types twice (declared and then defined)
  12. +
  13. Every name is typed twice (declared and then defined)
  14. Still stuck with strings when referring to class or role names
  15. Coercion gotcha from earlier still applies to types exported from MooseX::Types::Moose
  16. @@ -3044,15 +3068,6 @@ has transaction_history => (

    Questions?

    -
    -

    Exercises

    - -
    # cd exercises
    -# perl bin/prove -lv t/05-types.t
    -
    -Iterate til this passes all its tests
    -
    -

    Part 6: Advanced Attributes

    @@ -3150,7 +3165,7 @@ $alice->friend($bob);
    after salary_level => {
         my $self = shift;
    -    return unless @_;
    +    return unless @_;
         $self->clear_salary;
     };
    @@ -3162,11 +3177,22 @@ $alice->friend($bob);
    has salary_level => (
         is      => 'rw',
    -    trigger => sub { $_[0]->clear_salary },
    +    trigger =>
    +        sub { $_[0]->clear_salary },
     );
    +

    Trigger Arguments

    + + +
    + +

    Delegation

    @@ -3315,17 +3342,37 @@ has history => ( + + +
    +

    Native Delegation - Array(Ref)

    + +
    -

    Native Delegation - Array

    +

    Native Delegation - Array(Ref)

    package Person;
     use Moose;
     has _favorite_numbers => (
         traits   => [ 'Array' ],
    -    is       => 'ro',
    +    is       => 'bare',
         isa      => 'ArrayRef[Int]',
         default  => sub { [] },
         init_arg => undef,
    @@ -3337,23 +3384,71 @@ has _favorite_numbers => (
     
    -

    Native Delegation - Counter

    +

    Native Delegation - Array(Ref)

    + +
    my $person = Person->new();
    +
    +$person->add_favorite_number(7);
    +$person->add_favorite_number(42);
    +
    +print "$_\n"
    +    for $person->favorite_numbers;
    +
    +# 7
    +# 42
    +
    + +
    +

    Native Delegation

    + +
      +
    • Native types are ... +
        +
      • Number - add, mul, ...
      • +
      • String - append, chop, ...
      • +
      • Counter - inc, dec, ...
      • +
      • Bool - set, toggle, ...
      • +
      • Hash - get, set, ...
      • +
      • Array - already saw it
      • +
      • Code - execute and execute_method
      • +
      +
    • +
    +
    + +
    +

    Curried Delegation

    + +
      +
    • A delegation with some preset arguments
    • +
    • Works with object or Native delegation
    • +
    +
    + +
    +

    Curried Delegation

    -
    package Stack;
    +  
    package Person;
     use Moose;
    -has depth => (
    -    traits   => [ 'Counter' ],
    -    is       => 'ro',
    -    isa      => 'Int',
    -    default  => 0,
    -    init_arg => undef,
    -    handles  =>
    -      { _inc_depth => 'inc',
    -        _dec_depth => 'dec',
    -      },
    +has account => (
    +    is      => 'ro',
    +    isa     => 'BankAccount',
    +    handles => {
    +        receive_100 =>
    +            [ 'deposit', 100 ]
    +        give_100    =>
    +            [ 'withdraw', 100 ]
    +    },
     );
    +
    +

    Curried Delegation

    + +
    $person->receive_100;
    +# really is
    +$person->account->deposit(100);
    +

    Traits and Metaclasses

    @@ -3380,7 +3475,7 @@ has depth => (

    Traits and Metaclasses

      -
    • Can add/alter/remove attribute parameter (from has)
    • +
    • Can add/alter/remove an attribute parameter (from has)
    • Can change behavior of created attribute
    @@ -3438,15 +3533,12 @@ print Person->meta
  17. Use weak_ref to avoid circular references
  18. Use trigger to do an action post-attribute write
  19. Use delegations to hide "internal" objects
  20. +
  21. Use native delegations to treat Perl types as objects
  22. Traits and metaclasses let you extend Moose's core attribute features
  23. -

    Questions?

    -
    - -

    Exercises

    # cd exercises
    @@ -3456,20 +3548,228 @@ print Person->meta
     Iterate til this passes all its tests
    -
    -

    Part 7: Introspection

    +
    +

    CYOA

    + +

    + If there is time, keep going ... +

    + +

    + Otherwise, jump to slide 269 ... +

    -

    Part 8: A Tour of MooseX

    +

    Bonus: A Brief Tour of MooseX

    -
    -

    Part 9: Writing Moose Extensions

    +
    +

    Notable MX Modules on CPAN

    + +
      +
    • Not comprehensive
    • +
    • 152 MooseX distributions on CPAN as of 02/02/2010
    • +
    • Some of them are crap
    • +
    -
    -

    The End

    +
    +

    Already Mentioned Several

    + +
      +
    • MooseX::NonMoose - best solution for subclassing non-Moose parents
    • +
    • MooseX::Declare - real Perl 5 OO
    • +
    • MooseX::FollowPBP and MooseX::SemiAffordanceAccessor
    • +
    • MooseX::Params::Validate and MooseX::Method::Signatures
    • +
    • MooseX::Types
    • +
    +
    + +
    +

    MooseX::Declare

    + +
    use MooseX::Declare;
    +use 5.10.0; # for say
    +
    +class Person {
    +    has greeting =>
    +        ( is => 'ro', isa => 'Str' );
    +
    +    method speak {
    +        say $self->greeting;
    +    }
    +}
    +
    + +
    +

    MooseX::Declare

    + +
      +
    • Still experimental-ish, but seeing more and more use
    • +
    • Not a source filter!
    • +
    • Hooks into the Perl parser rather than filtering all your code
    • +
    • But not supported by PPI, perltidy, etc.
    • (yet?) +
    +
    + +
    +

    MooseX::StrictConstructor

    + +
      +
    • By default, unknown constructor arguments are ignored
    • +
    • MX::StrictConstructor turns these into an error
    • +
    +
    + +
    +

    MooseX::StrictConstructor

    + +
    package Person;
    +
    +use Moose;
    +use MooseX::StrictConstructor;
    +
    +has name => ( is => 'ro' );
    +
    +Person->new
    +    ( nane => 'Ringo Shiina' ); # kaboom
    +
    + +
    +

    MooseX::Traits

    + +
      +
    • Combines object construction and role application
    • +
    • Makes it easy to create one-off customized objects
    • +
    +
    + +
    +

    MooseX::Traits

    + +
    package MyApp::Thingy;
    +use Moose;
    +
    +with 'MooseX::Traits';
    +
    +my $thing =
    +    MyApp::Thingy->new_with_traits
    +        ( traits => [ 'Foo', 'Bar' ],
    +          size   => 42 );
    +
    + +
    +

    MooseX::Getopt

    + +
      +
    • Makes command-line interface programs easy!
    • +
    • Construct an object from CLI arguments
    • +
    +
    + +
    +

    MooseX::Getopt

    + +
    package App::CLI;
    +use Moose;
    +
    +with 'MooseX::Getopt';
    +
    +has file    =>
    +    ( is => 'ro', required => 1 );
    +has filters =>
    +    ( is => 'ro', isa => 'ArrayRef[Str]' );
    +
    +sub run { ... }
    +
    + +
    +

    MooseX::Getopt

    + +
      +
    • Then call it like this:
    • +
    + +
    #!/usr/bin/perl
    +
    +use App::CLI;
    +
    +App::CLI->new_with_options()->run();
    + +
    $ myapp-cli \
    +   --file foo \
    +   --filters compress \
    +   --filters sanitize
    +
    + +
    +

    MooseX::Clone

    + +
    package Person;
    +
    +use Moose;
    +with 'MooseX::Clone';
    +
    +my $person = Person->new;
    +my $clone  = $person->clone;
    +
    + +
    +

    MooseX::NonMoose

    + +
      +
    • Highly recommended for subclassing non-Moose parents
    • +
    • Gets all the little annoying details right
    • +
    +
    + +
    +

    MooseX::Role::Parameterized

    + +
    package HasCollection;
    +use MooseX::Role::Parameterized;
    +parameter type => ( isa     => 'Str',
    +                    default => 'Item' );
    +role {
    +    my $p = shift;
    +
    +    my $type =
    +        'ArrayRef[' . $p->type() . ']';
    +    has collection =>
    +        ( is  => 'ro',
    +          isa => $type );
    +};
    +
    + +
    +

    MooseX::Role::Parameterized

    + +
    package Person;
    +
    +use Moose;
    +with HasCollection => { type => 'Int' };
    +
    + +
    +

    Questions?

    +
    + +
    +

    Moose-using Modules

    + +

    + For further reading, a few modules which use Moose ... +

    + +
    @@ -3482,10 +3782,14 @@ Iterate til this passes all its tests
  24. mailing list - moose@perl.org
  25. Slides and exercises are in Moose's git repo:
    - git://jules.scsys.co.uk/gitmo/moose-presentations
  26. + git://jules.scsys.co.uk/gitmo/moose-presentations
    +
    +

    The End

    +
    +