X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=moose-class%2Fslides%2Findex.html;h=df47d7da6a22df25d3ad0adb40ca39d19134259d;hb=f5cc2f3e2e4b43900ab65afe4f5289d6ea551915;hp=64228049fc1921c11c82f68fefdc2685093fde9f;hpb=84326b8a3635da8d4c825df6f2862f4e4c536fcc;p=gitmo%2Fmoose-presentations.git
diff --git a/moose-class/slides/index.html b/moose-class/slides/index.html
index 6422804..df47d7d 100644
--- a/moose-class/slides/index.html
+++ b/moose-class/slides/index.html
@@ -52,7 +52,7 @@ img#me05 {top: 43px;left: 36px;}
Introduction to Moose
-
+
Dave Rolsky
@@ -218,7 +218,7 @@ use Moose;
- AKA advice
- "Before foo(), do this first"
- - "Do this after foo()
+ - "Do this after foo()"
- "Put this code around foo()"
@@ -300,8 +300,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
@@ -892,7 +892,7 @@ use Moose;
BUILDARGS
- - Takes
@_
, returns a hash reference of attribute names/value
+ - Takes
@_
, returns a hash reference of attribute name/value pairs
- Accepts a hash or hashref; throws otherwise
- Provide your own for other cases
- Always call
$class->SUPER::BUILDARGS(@_)
as a fallback!
@@ -951,11 +951,11 @@ sub BUILD {
Person->new(@_)
-
+
- Calls
Person->BUILDARGS(@_)
to turn @_
into a hashref
- Blesses a reference
- Populates attributes based on the hashref from #1
- - Calls
$new_object->BUILDALL($constructor_args)
+ - Calls
$new_object->BUILDALL($constructor_args)
... which calls all BUILD
methods
- Returns the object
@@ -1066,6 +1066,7 @@ use Moose;
- Mostly like
$self->SUPER::work(@_)
- But cannot change
@_
!
- Binds the parent's method at compile time
+ - Parent determined by checking
Child->meta()->superclasses()
@@ -1106,8 +1107,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
@@ -1126,7 +1126,7 @@ print $person->first_name; # Dave
use Moose;
# true
-Person->can('extends');
+Person->can('extends');
- Not very hygienic
@@ -1141,17 +1141,31 @@ use Moose;
...
-no Moose;
+no Moose;
+
+# false
+Person->can('extends');
+
+
+
+
Cleaning Up Moose Droppings
+
+
package Person;
+use namespace::autoclean;
+use Moose;
+
+...
# false
-Person->can('extends');
+Person->can('extends');
No Moose
- no Moose
at the end of a package is a best practice
+ - Cleaning up is a best practice
+ - Say
no Moose
at the end of a package
- Or
use namespace::autoclean
at the top
- Just do it
@@ -1161,13 +1175,13 @@ Person->can('extends');
Immutability
- - Stevan's Incantation of Fleet-Footedness
+ - Stevan's Incantation of Fleet-Footedness
package Person;
use Moose;
-__PACKAGE__->meta->make_immutable;
+
__PACKAGE__->meta->make_immutable;
@@ -1353,7 +1367,7 @@ sub print {
# or ...
-Person->meta->does('Printable')
+Person->meta->does_role('Printable')
@@ -1413,69 +1427,17 @@ use Moose;
-
Method Aliasing
-
-
package FragileDancer;
-use Moose;
-
-with 'IsFragile' =>
- { -alias =>
- { break => 'break_bone' } },
- 'CanBreakdance' =>
- { -alias =>
- { break => 'break_it_down' } };
-
-
- - Renames the roles' methods
- - Still conflicts, need to
exclude
as well
-
-
-
-
-
Method Exclusion
-
-
package FragileDancer;
-use Moose;
-
-with 'IsFragile' =>
- { -alias =>
- { break => 'break_bone' },
- -excludes => 'break' },
- 'CanBreakdance' =>
- { -alias =>
- { break => 'break_it_down' },
- -excludes => 'break' };
-
-
-
-
And then ...
-
-
package FragileDancer;
-use Moose;
-
-sub break {
- my $self = shift;
-
- $self->break_it_down;
- if ( rand(1) < 0.5 ) {
- $self->break_bone;
- }
-}
-
-
-
-
Still Full of Fail
+
Conflicts Are a Smell
- - Roles are also about semantics!
- - We've fulfilled the letter and lost the spirit
+ - Roles are about semantics!
- Roles have a meaning
- - Think twice before blindly aliasing and excluding methods!
+ - Method name conflicts smell like bad design
-
Hot Role-on-Role Action
+
Roles With Roles
package Comparable;
use Moose::Role;
@@ -1484,7 +1446,7 @@ requires 'compare';
-
Hot Role-on-Role Action
+
Roles With Roles
package TestsEquality;
use Moose::Role;
@@ -1493,7 +1455,7 @@ with 'Comparable';
sub is_equal {
my $self = shift;
- return $self->compare(@_) == 0;
+ return $self->compare(@_) == 0;
}
@@ -1508,8 +1470,8 @@ with 'TestsEquality';
# Satisfies the Comparable role
sub compare { ... }
-Integer->does('TestsEquality'); # true
-Integer->does('Comparable'); # also true!
+Integer->does('TestsEquality'); # true
+Integer->does('Comparable'); # also true!
@@ -1531,11 +1493,11 @@ with 'HasSubProcess';
Delayed Conflict
-
package StateOfTexas;
+ package SysadminAssassin;
with 'Killer';
- StateOfTexas
must implement its own execute
+ SysadminAssassin
must implement its own execute
- But loading the
Killer
role by itself does not cause an error
@@ -1616,7 +1578,7 @@ has [ 'left', 'right' ] => (
use Moose::Util qw( apply_all_roles );
-my $fragile_person = Person->new( ... );
+my $fragile_person = Person->new( ... );
apply_all_roles( $fragile_person,
'IsFragile' );
@@ -1772,8 +1734,8 @@ has first_name => (
required => 1,
);
-
Person->new( first_name => undef ); # ok
-Person->new(); # kaboom
+
Person->new( first_name => undef ); # ok
+Person->new(); # kaboom
@@ -1866,7 +1828,8 @@ has packages => (
use Moose;
my $highlander_bank =
- Bank->new( name => 'Spire FCU' );
+ Bank->new(
+ name => 'Clan MacLeod Trust' );
has bank => (
is => 'rw',
@@ -1878,7 +1841,8 @@ has bank => (
Builder
- - A method name which returns the default
+ - A method name
+ - When called, this method returns the default value
@@ -1952,7 +1916,8 @@ has bank => (
use Moose;
has shoe_size => (
- is => 'ro',
+ is => 'ro',
+ required => 1,
);
@@ -2040,11 +2005,11 @@ has shoe_size => (
init_arg => 'foot_size',
);
-Person->new( shoe_size => 13 );
+Person->new( shoe_size => 13 );
my $person =
- Person->new( foot_size => 13 );
-print $person->shoe_size;
+ Person->new( foot_size => 13 );
+print $person->shoe_size;
@@ -2058,7 +2023,7 @@ has shoes => (
init_arg => undef,
);
-Person->new( shoes => Shoes->new );
+Person->new( shoes => Shoes->new );
@@ -2205,6 +2170,13 @@ has first_name => (
- Attributes can have a
default
or builder
- Attributes with a default or builder can be
lazy
- Attributes can have a
clearer
and/or predicate
+
+
+
+
+
Basic Attributes Summary
+
+
- An attribute's constructor name can be changed with
init_arg
- A subclass can alter its parents' attributes
- Attribute accessor names can be changed
@@ -2234,18 +2206,18 @@ Iterate til this passes all its tests
- Apply to an existing method
- - ... from a parent class, the current class, or a role
+ - ... that comes from a parent class, the current class, or a role
- Roles can provide modifiers that are applied at composition time
-
What is a Method Modifier
+
What Are Method Modifiers For?
- "Inject" behavior
- Add behavior to generated methods (accessors, delegations)
- - Provide roles which modify existing behavior
+ - Added from a role, can modify existing behavior
@@ -2372,7 +2344,7 @@ after clear_password => sub {
$self->$orig(
$self->_munge_insert(@_) );
- $new_user->_assign_uri;
+ $new_user->_assign_uri;
return $new_user;
};
@@ -2436,6 +2408,7 @@ around run => sub {
- Inverted
super
- From least- to most-specific
+ - Like Mason's autohandler feature
- Grandparent to parent to child
- Not allowed in roles
@@ -2444,19 +2417,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() };
@@ -2578,11 +2553,11 @@ Item
Undef
Defined
Value
- Str
- Num
- Int
- ClassName
- RoleName
+ Str
+ Num
+ Int
+ ClassName
+ RoleName
@@ -2600,7 +2575,7 @@ Item
CodeRef
RegexpRef
GlobRef
- FileHandle
+ FileHandle
Object
@@ -2732,9 +2707,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 { ... };
@@ -2744,10 +2721,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' ) },
@@ -2758,9 +2737,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 ) },
@@ -2771,12 +2752,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 { ... };
@@ -2892,6 +2875,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;
@@ -3034,7 +3030,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']
@@ -3047,7 +3043,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
@@ -3068,15 +3064,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
@@ -3174,7 +3161,7 @@ $alice->friend($bob);
after salary_level => {
my $self = shift;
- return unless @_;
+ return unless @_;
$self->clear_salary;
};
@@ -3186,11 +3173,22 @@ $alice->friend($bob);
has salary_level => (
is => 'rw',
- trigger => sub { $_[0]->clear_salary },
+ trigger =>
+ sub { $_[0]->clear_salary },
);
+
Trigger Arguments
+
+
+ $self
+ $new_value
+ $old_value
- if one exists
+
+
+
+
Delegation
@@ -3247,6 +3245,7 @@ has lungs => (
Array Reference
+ - 1-to-1 mapping
- Takes each method name and creates a simple delegation from the delegating class to the delegatee attribute
@@ -3369,7 +3368,7 @@ has history => (
use Moose;
has _favorite_numbers => (
traits => [ 'Array' ],
- is => 'ro',
+ is => 'bare',
isa => 'ArrayRef[Int]',
default => sub { [] },
init_arg => undef,
@@ -3407,7 +3406,7 @@ print "$_\n"
Bool - set
, toggle
, ...
Hash - get
, set
, ...
Array - already saw it
- Code - execute
, that's it
+ Code - execute
and execute_method
@@ -3472,7 +3471,7 @@ $person->account->deposit(100);
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
@@ -3530,6 +3529,7 @@ print Person->meta
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 let you extend Moose's core attribute features
@@ -3548,12 +3548,31 @@ print Person->meta
Iterate til this passes all its tests
+
+
Questions?
+
+
-
Part 7: Introspection
+ The End
+
+
+
+
-
Part 8: A Brief Tour of MooseX
+ Bonus: A Brief Tour of MooseX
@@ -3561,7 +3580,7 @@ Iterate til this passes all its tests
- Not comprehensive
- - 128 MooseX distributions on CPAN as of 09/24/2009
+ - 152 MooseX distributions on CPAN as of 02/02/2010
- Some of them are crap
@@ -3570,11 +3589,11 @@ Iterate til this passes all its tests
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::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
@@ -3585,8 +3604,8 @@ Iterate til this passes all its tests
use 5.10.0; # for say
class Person {
- has greeting
- => ( is => 'ro', isa => 'Str' );
+ has greeting =>
+ ( is => 'ro', isa => 'Str' );
method speak {
say $self->greeting;
@@ -3601,6 +3620,7 @@ class Person {
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?)
@@ -3608,7 +3628,7 @@ class Person {
MooseX::StrictConstructor
- - By default, unknown constructor arguments are ignore
+ - By default, unknown constructor arguments are ignored
- MX::StrictConstructor turns these into an error
@@ -3670,7 +3690,7 @@ use Moose;
has file =>
( is => 'ro', required => 1 );
has filters =>
- ( is => 'ro', isa => 'Str' );
+ ( is => 'ro', isa => 'ArrayRef[Str]' );
sub run { ... }
@@ -3686,7 +3706,7 @@ sub run { ... }
use App::CLI;
-App::CLI->new_with_options()->run();
+App::CLI->new_with_options()->run();
$ myapp-cli \
--file foo \
@@ -3742,30 +3762,8 @@ use Moose;
with HasCollection => { type => 'Int' };
-
-
Questions?
-
-
-
Part 9: Writing Moose Extensions
-
-
-
-
The End
-
-
-
-
More Information
-
-
+
The End (Really)