X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=moose-class%2Fslides%2Findex.html;h=b065633f79232569c9117da03886f1ee22399a65;hb=6960f4e1f61fa7cdb54cae31ce4e60d513469d6a;hp=81db5110e0c836e97fb4fda9c219c3cf00c5d3b9;hpb=4a2daaa5e6a7a78149d61c25aee24eae9031e11b;p=gitmo%2Fmoose-presentations.git diff --git a/moose-class/slides/index.html b/moose-class/slides/index.html index 81db511..b065633 100644 --- a/moose-class/slides/index.html +++ b/moose-class/slides/index.html @@ -40,7 +40,7 @@ img#me05 {top: 43px;left: 36px;}
@@ -284,10 +297,10 @@ use Moose; has blog_uri => ( is => 'rw', isa => 'URI', - handles => { 'blog_hostname' => 'host' }, + handles => { 'blog_host' => 'host' }, ); -$person->blog_hostname; +$person->blog_host; # really calls $person->blog_uri->host
@@ -829,6 +842,16 @@ has last_name => ( ); +
+

More Why Moose?

+ + +
+

Part 1: Moose Classes

@@ -869,7 +892,7 @@ use Moose;

BUILDARGS

@@ -1126,7 +1152,9 @@ Person->can('extends');

No Moose

@@ -1187,13 +1215,15 @@ use Moose;

Exercises

# cd exercises
-# perl install-moose (if needed)
+
 # perl bin/prove -lv t/00-prereq.t
 
-Missing anything? Install it. (see tarballs/)
+# perl install-moose (if needed)
 
 # perl bin/prove -lv t/01-classes.t
 
+# edit lib/Person.pm and lib/Employee.pm
+
 Iterate til this passes all its tests
@@ -1211,11 +1241,10 @@ Iterate til this passes all its tests
-

Roles Can Have State and Behavior

+

Roles - State and Behavior

package HasPermissions;
 use Moose::Role;
-
 # state
 has access_level => ( is => 'rw' );
 
@@ -1224,7 +1253,8 @@ sub can_access {
     my $self     = shift;
     my $required = shift;
 
-    return $self->access_level >= $required;
+    return $self->access_level
+             >= $required;
 }
@@ -1268,8 +1298,8 @@ with 'HasPermissions';

Classes Consume Roles

my $person = Person->new(
-    first_name => 'Kenichi',
-    last_name => 'Asai',
+    first_name   => 'Kenichi',
+    last_name    => 'Asai',
     access_level => 42,
 );
 
@@ -1325,7 +1355,7 @@ sub print {
 
 # or ...
 
-if ( Person->meta->does('Printable') ) { ... }
+Person->meta->does('Printable') @@ -1391,10 +1421,10 @@ use Moose; use Moose; with 'IsFragile' => - { alias => + { -alias => { break => 'break_bone' } }, 'CanBreakdance' => - { alias => + { -alias => { break => 'break_it_down' } }; + + +
+

Basic Attributes Summary

+ +
@@ -2203,18 +2246,18 @@ Iterate til this passes all its tests
-

What is a Method Modifier

+

What Are Method Modifiers For?

@@ -2258,7 +2301,8 @@ before work => sub { my $self = shift; return unless $DEBUG; - warn "Called work on ", $self->full_name, + warn "Called work on ", + $self->full_name, "with the arguments: [@_]\n"; }; @@ -2290,19 +2334,17 @@ after work => sub {
-

Other Uses Example

+

More Modifier Examples

has password => (
      is      => 'rw',
      clearer => 'clear_password',
 );
-
 has hashed_password => (
      is      => 'ro',
      builder => '_build_hashed_password',
      clearer => '_clear_hashed_password',
 );
-
 after clear_password => sub {
     my $self = shift;
     $self->_clear_hashed_password;
@@ -2343,7 +2385,6 @@ after clear_password => sub {
             $self->_munge_insert(@_) );
 
     $new_user->_assign_uri;
-
     return $new_user;
 };
@@ -2352,7 +2393,7 @@ after clear_password => sub {

Modifier Order

@@ -2407,6 +2448,7 @@ around run => sub { @@ -2421,13 +2463,11 @@ sub xml { '<doc>' . inner() . '</doc> package Report; extends 'Document'; - augment xml => sub { title() . inner() . summary() }; package TPSReport; extends 'Report'; - augment xml => sub { tps_xml() . inner() }; @@ -2508,7 +2548,8 @@ extends 'Report';

Exercises

# cd exercises
-# perl bin/prove -lv t/04-method-modifiers.t
+# perl bin/prove -lv \
+      t/04-method-modifiers.t
 
 Iterate til this passes all its tests
@@ -2550,11 +2591,10 @@ Item Undef Defined Value - Num - Int - Str - ClassName - RoleName + Str + Num + Int + ClassName @@ -2564,6 +2604,7 @@ Item
 (Item)
     (Defined)
+        (Value)
         Ref
             ScalarRef
             ArrayRef[`a]
@@ -2571,7 +2612,7 @@ Item
             CodeRef
             RegexpRef
             GlobRef
-              FileHandle
+                FileHandle
             Object
 
@@ -2602,6 +2643,7 @@ undef @@ -2662,8 +2704,9 @@ undef subtype 'PositiveInt', as 'Int', where { $_ > 0 }, - message { "The value you provided ($_)" - . " was not a positive number." }; + message + { "The value you provided ($_)" + . " was not a positive int." }; has size => ( is => 'ro', @@ -2701,9 +2744,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 { ... };
@@ -2713,9 +2758,11 @@ subtype 'DateTime',

Subtype Shortcuts - role_type

use Moose::Util::TypeConstraints;
-role_type 'Printable';
+role_type 'Printable';
-subtype 'Printable', +
+ +
subtype 'Printable',
     as      'Object',
     where
         { Moose::Util::does_role(
@@ -2727,9 +2774,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 ) },
@@ -2740,9 +2789,13 @@ 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 }
+             qw( red blue green );
 
-my %ok = map { $_ => 1 } qw( red blue green );
 subtype 'Color'
     as      'Str',
     where   { $ok{$_} },
@@ -2774,9 +2827,13 @@ has size => (
 
 subtype 'UCStr',
     as    'Str',
-    where { ! /[a-z]/ };
+    where { ! /[a-z]/ };
+ -coerce 'UCStr', +
+

Coercions

+ +
coerce 'UCStr',
     from 'Str',
     via  { uc };
 
@@ -2815,18 +2872,15 @@ coerce 'My::DateTime',
     via  { [ $_ ] };
    -
  • Coerce instead of a union like Int | ArrayRef[Int]
  • +
  • Instead of union - Int | ArrayRef[Int]
-

Using Types with Attributes

package Person;
 
-use Moose::Util::TypeConstraints;
-
 has height => (
     is  => 'rw',
     isa => 'Num',
@@ -2840,6 +2894,24 @@ has favorite_numbers => (
 
+

More Droppings

+ +
    +
  • Moose::Util::TypeConstraints also needs cleanup
  • +
+ +
package Person;
+
+use Moose;
+use Moose::Util::TypeConstraints;
+
+subtype ...;
+
+no Moose;
+no Moose::Util::TypeConstraints;
+
+ +

Typed Methods (Low-tech)

package Person;
@@ -2852,12 +2924,11 @@ sub work {
             \@_,
             tasks    =>
                 { isa    => 'ArrayRef[Task]',
-                  coerce =>1 },
+                  coerce => 1 },
             can_rest =>
                 { isa     => 'Bool',
                   default => 0 },
         );
-
     ...
 }
@@ -2881,7 +2952,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
@@ -2910,7 +2981,6 @@ sub work {

Namespace Fix

use Moose::Util::TypeConstraints;
-
 subtype 'MyApp::Type::DateTime',
     as 'DateTime';
 
@@ -2984,7 +3054,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']
@@ -2997,7 +3067,7 @@ has transaction_history => (
  • Catches typos at compile time
  • Automatic namespacing
  • One more thing to install and learn
  • -
  • Every name gets types twice (declared and then defined)
  • +
  • Every name is typed twice (declared and then defined)
  • Still stuck with strings when referring to class or role names
  • Coercion gotcha from earlier still applies to types exported from MooseX::Types::Moose
  • @@ -3090,7 +3160,8 @@ $alice->friend($bob);
    use Moose; has name => ( is => 'ro' ); -has friend => ( is => 'rw', weak_ref => 1 ); +has friend => ( is => 'rw', + weak_ref => 1 ); my $alice = Person->new( name => 'Alice' ); my $bob = Person->new( name => 'Bob' ); @@ -3123,7 +3194,7 @@ $alice->friend($bob);
    after salary_level => {
         my $self = shift;
    -    return unless @_;
    +    return unless @_;
         $self->clear_salary;
     };
    @@ -3135,7 +3206,8 @@ $alice->friend($bob);
    has salary_level => (
         is      => 'rw',
    -    trigger => sub { $_[0]->clear_salary },
    +    trigger =>
    +        sub { $_[0]->clear_salary },
     );
    @@ -3196,6 +3268,7 @@ has lungs => (

    Array Reference

    @@ -3209,7 +3282,6 @@ has lungs => (
    package Person;
     use Moose;
    -
     has account => (
         is      => 'ro',
         isa     => 'BankAccount',
    @@ -3257,7 +3329,6 @@ has name => (
     
       
    package Auditor;
     use Moose::Role;
    -
     sub record_change  { ... }
     sub change_history { ... }
     
    @@ -3285,6 +3356,120 @@ has history => (
     
     
     
    +

    Native Delegation

    + +
      +
    • Delegate to unblessed Perl types
    • +
    • Scalar, array or hash ref, etc
    • +
    • Treat Perl types as objects
    • +
    • Still uses handles
    • +
    • Pretend that native Perl types have methods
    • +
    +
    + +
    +

    Native Delegation - Array(Ref)

    + +
      +
    • Methods include: +
        +
      • push
      • +
      • shift
      • +
      • elements - returns all elements
      • +
      • count
      • +
      • is_empty
      • +
      • quite a few more
      • +
      +
    • +
    +
    + +
    +

    Native Delegation - Array(Ref)

    + +
    package Person;
    +use Moose;
    +has _favorite_numbers => (
    +    traits   => [ 'Array' ],
    +    is       => 'ro',
    +    isa      => 'ArrayRef[Int]',
    +    default  => sub { [] },
    +    init_arg => undef,
    +    handles  =>
    +      { favorite_numbers    => 'elements',
    +        add_favorite_number => 'push',
    +      },
    +);
    +
    + +
    +

    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 Person;
    +use Moose;
    +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

      @@ -3309,7 +3494,7 @@ has history => (

      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
    @@ -3327,7 +3512,6 @@ has ssn => ( isa => 'Str', label => 'Social Security Number', ); - print Person->meta ->get_attribute('ssn')->label;
    @@ -3346,7 +3530,6 @@ has ssn => ( isa => 'Str', label => 'Social Security Number', ); - print Person->meta ->get_attribute('ssn')->label;
    @@ -3381,7 +3564,8 @@ print Person->meta

    Exercises

    # cd exercises
    -# perl bin/prove -lv t/06-advanced-attributes.t
    +# perl bin/prove -lv \
    +      t/06-advanced-attributes.t
     
     Iterate til this passes all its tests
    @@ -3391,9 +3575,200 @@ Iterate til this passes all its tests
    -

    Part 8: A Tour of MooseX

    +

    Part 8: A Brief Tour of MooseX

    +
    + +
    +

    Notable MX Modules on CPAN

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

    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?

    +
    +

    Part 9: Writing Moose Extensions

    @@ -3412,7 +3787,7 @@ Iterate til this passes all its tests
  • mailing list - moose@perl.org
  • Slides and exercises are in Moose's git repo:
    - git://jules.scsys.co.uk/gitmo/moose-presentations
  • + git://jules.scsys.co.uk/gitmo/moose-presentations