X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=moose-class%2Fslides%2Findex.html;h=e8302e4e73cbe636f765ed888232e74e28c1cd6d;hb=a88cc08084397dc7667e26dc315fb5492d8bf558;hp=1019d9993aae64d29abf1d9e7ad2736d35f47d53;hpb=b9a2a53f67245562693a09ef80bd9bd80340f5f7;p=gitmo%2Fmoose-presentations.git diff --git a/moose-class/slides/index.html b/moose-class/slides/index.html index 1019d99..e8302e4 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;}
@@ -144,7 +155,7 @@ img#me05 {top: 43px;left: 36px;}
package Person;
 use Moose;
 
-has first_name => ( is => 'rw' );
+has first_name => ( is => 'ro' ); @@ -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
@@ -832,6 +843,16 @@ has last_name => ( );
+
+

More Why Moose?

+ + +
+

Part 1: Moose Classes

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

BUILDARGS

@@ -929,13 +950,13 @@ sub BUILD {

Object Construction a la Moose

-
Person->new(@_)
+
Person->new(@args)
-
    -
  1. Calls Person->BUILDARGS(@_) to turn @_ into a hashref
  2. +
      +
    1. Calls Person->BUILDARGS(@args) to turn @args 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 { @@ -1009,7 +1032,7 @@ extends 'LWP';
  • No DEMOLISH()
  • -
  • But see MooseX::NonMoose for a workaround
  • +
  • But MooseX::NonMoose fixes all of this
  • @@ -1019,6 +1042,7 @@ extends 'LWP'; @@ -1030,13 +1054,13 @@ use Moose; extends 'Person'; -override work => sub { +override work => sub { my $self = shift; die "Pay me first" unless $self->got_paid; - super(); -}; + super(); +};
    @@ -1045,7 +1069,8 @@ use Moose;
    @@ -1086,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 @@ -1106,7 +1130,7 @@ print $person->first_name; # Dave use Moose; # true -Person->can('extends'); +Person->can('extends'); - - -
    -

    Method Modifiers Summary

    - -
    @@ -2558,11 +2449,11 @@ Item Undef Defined Value - Num - Int - Str - ClassName - RoleName + Str + Num + Int + ClassName + RoleName @@ -2580,7 +2471,7 @@ Item CodeRef RegexpRef GlobRef - FileHandle + FileHandle Object @@ -2589,15 +2480,12 @@ Item

    Bool

    True

    -
    1
    -924.1
    -'true'
    -{}
    +
    1

    False

    0
    -0.0
     '0'
    +''
     undef
    +

    Specio

    + + +
    + +

    Recommendation

    -
    -

    Exercises

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

    Part 6: Advanced Attributes

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

    Trigger Arguments

    + + +
    + +

    Delegation

    +

    Delegation Explained

    + +
    package Person;
    +
    +has lungs => (
    +    is      => 'ro',
    +    isa     => 'Lungs',
    +    handles => [ 'inhale', 'exhale' ],
    +);
    +
    +sub inhale {
    +    my $self = shift;
    +    $self->lungs()->inhale();
    +}
    +
    +sub exhale { ... }
    +
    + +

    Why Delegation?

    @@ -3258,8 +3220,12 @@ has account => ( }, @@ -3318,17 +3284,36 @@ has history => (
    -

    Native Delegation - Array

    +

    Native Delegation - Array(Ref)

    + + +
    + +
    +

    Native Delegation - Array(Ref)

    package Person;
     use Moose;
     has _favorite_numbers => (
    -    traits   => [ 'Array' ],
    -    is       => 'ro',
    +    traits   => [ 'Array' ],
         isa      => 'ArrayRef[Int]',
         default  => sub { [] },
         init_arg => undef,
    @@ -3340,139 +3325,320 @@ 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

    + + +
    + +
    +

    Curried 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

    +

    Advanced Attributes Summary

      -
    • The ultimate in customization
    • -
    • Per attribute metaclasses
    • -
    • Per attribute roles applied to the attribute metaclass
    • -
    • Change the meta-level behavior
    • +
    • Use weak_ref to avoid circular references
    • +
    • Use trigger to do an action post-attribute write
    • +
    • Use delegations to hide "internal" objects
    • +
    • Use native delegations to treat Perl types as objects
    -

    Traits and Metaclasses

    +

    Questions?

    +
    + +
    +

    Exercises

    + +
    # cd exercises
    +# perl bin/prove -lv \
    +      t/06-advanced-attributes.t
    +
    +Iterate til this passes all its tests
    +
    + +
    +

    CYOA

    + +

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

    + +

    + Otherwise, jump to slide 269 ... +

    +
    + +
    +

    Bonus: A Brief Tour of MooseX

    +
    + +
    +

    Notable MX Modules on CPAN

      -
    • The default metaclass is Moose::Meta::Attribute
    • -
    • Controls accessor generation, defaults, delegation, etc.
    • -
    • Adding a role to this metaclass (or replacing it) allows for infinite customization
    • +
    • Not comprehensive
    • +
    • 188 MooseX distributions on CPAN as of 02/03/2011
    • +
    • Some of them are crap
    -

    Traits and Metaclasses

    +

    Already Mentioned Several

      -
    • Can add/alter/remove attribute parameter (from has)
    • -
    • Can change behavior of created attribute
    • +
    • 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.12.0; # for say
    +
    +class Person {
    +    has greeting =>
    +        ( is => 'ro', isa => 'Str' );
    +
    +    method speak {
    +        say $self->greeting;
    +    }
    +}
    -

    Simple Trait Example

    +

    MooseX::Declare

    -
    package Person;
    -use Moose;
    -use MooseX::LabeledAttributes;
    +  
      +
    • 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?)
    • +
    +
    -has ssn => ( - traits => [ 'Labeled' ], - is => 'ro', - isa => 'Str', - label => 'Social Security Number', -); -print Person->meta - ->get_attribute('ssn')->label; +
    +

    MooseX::StrictConstructor

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

    Simple Metaclass Example

    +

    MooseX::StrictConstructor

    package Person;
    +
     use Moose;
    -use MooseX::LabeledAttributes;
    +use MooseX::StrictConstructor;
     
    -has ssn => (
    -    metaclass =>
    -        'MooseX::Meta::Attribute::Labeled',
    -    is        => 'ro',
    -    isa       => 'Str',
    -    label     => 'Social Security Number',
    -);
    -print Person->meta
    -            ->get_attribute('ssn')->label;
    +has name => ( is => 'ro' ); + +Person->new + ( nane => 'Ringo Shiina' ); # kaboom
    -

    Traits vs Metaclass

    +

    MooseX::Traits

    -

    Advanced Attributes Summary

    +

    MooseX::Traits

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

    MooseX::Getopt

    -

    Questions?

    -
    +

    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 { ... }
    +
    -

    Exercises

    +

    MooseX::Getopt

    -
    # cd exercises
    -# perl bin/prove -lv \
    -      t/06-advanced-attributes.t
    +  
      +
    • Then call it like this:
    • +
    -Iterate til this passes all its tests
    +
    #!/usr/bin/perl
    +
    +use App::CLI;
    +
    +App::CLI->new_with_options()->run();
    + +
    $ myapp-cli \
    +   --file foo \
    +   --filters compress \
    +   --filters sanitize
    -
    -

    Part 7: Introspection

    +
    +

    MooseX::Clone

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

    Part 8: A Tour of MooseX

    +
    +

    MooseX::NonMoose

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

    Part 9: Writing Moose Extensions

    +
    +

    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 );
    +};
    -
    -

    The End

    +
    +

    MooseX::Role::Parameterized

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

    Questions?

    +
    + +
    +

    Moose-using Modules

    + +

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

    + +
    @@ -3480,22 +3646,26 @@ Iterate til this passes all its tests
    +
    +

    The End

    +
    +