MO SE                          o                         a guide to the                              new revolutionThursda...
Thursday, July 19, 12
Moose                        http://rjbs.manxome.org/talks/moose/Thursday, July 19, 12
Any         Questions?Thursday, July 19, 12(questions about demographics of the audience)who is using Moose? who knows the...
???? Moose ????Thursday, July 19, 12
???? Moose ????               • Moose is the new black               •Thursday, July 19, 12
???? Moose ????               • Moose is the new blackThursday, July 19, 12None of this answers the real question:
???? Moose ????               • Moose is the new blackThursday, July 19, 12None of this answers the real question:
???? Moose ????               • Moose is the new black               • Moose is at the heart of the new revolutionThursday...
???? Moose ????               • Moose is the new black               • Moose is at the heart of the new revolution        ...
Thursday, July 19, 12...what is Moose?
MooseThursday, July 19, 12
Moose               • Moose is a toolkit for writing classesThursday, July 19, 12
Moose               • Moose is a toolkit for writing classes               • with some mixin-like featuresThursday, July 1...
Moose               • Moose is a toolkit for writing classes               • with some mixin-like features               •...
??????????????????  ??????????????????  ??????????????????  ??????????????????  ??????????????????  ??????????????????  ??...
Perl 5s Object SystemThursday, July 19, 12
Perl 5s Object System                        • bare bones - a toolkitThursday, July 19, 12
Perl 5s Object System                        • bare bones - a toolkit                        • very few assumptionsThursda...
Perl 5s Object System                        • bare bones - a toolkit                        • very few assumptions       ...
Perl 5s Object System                        • bare bones - a toolkit                        • very few assumptions       ...
Theres more than                 one way to do it!Thursday, July 19, 12For example, lets talk about object systems -- sinc...
Theres more than                 one way to do it!                 ...but sometimes consistency is not a bad thing eitherT...
class Employee        attr_accessor :name        attr_accessor :title      endThursday, July 19, 12Ruby
(defclass Employee ()        ((Name :accessor Name :initarg :Name)         (Title :accessor Title :initarg :Title)))Thursd...
class Employee {        public var $name;        public var $title;      }Thursday, July 19, 12PHP (!)
class Employee {        has Str $.name;        has Str $.title;      }Thursday, July 19, 12Perl 6
package Employee;      sub new { bless {} }      for my $attr (qw(name title)) {        no strict;        *$attr = sub {  ...
class Employee {        has Str $.name;        has Str $.title;      }Thursday, July 19, 12and all the associated nice, si...
package Employee;      sub new { bless {} }      for my $attr (qw(name title)) {        no strict;        *$attr = sub {  ...
package Employee;      use Moose;      has name => (is => ro);      has title => (is => rw);Thursday, July 19, 12Isnt that...
Thursday, July 19, 12Thats a pretty nice savings. Also, notice the typo in the right-hand side? No. Of course youdidnt!Now...
Dungeons                           &                        Dragons                           &                         Mo...
Jeffs Gameblog                                  http://www.jrients.blogspot.com/Thursday, July 19, 12This is one of my fav...
Jeffs Gameblog                                  http://www.jrients.blogspot.com/Thursday, July 19, 12This is one of my fav...
Two Third Level SpellsThursday, July 19, 12obviously FB is more powerful! so why is it third level?Jeff wondered the same ...
Two Third Level Spells                        • Fireball                         • automatic hit, big damage, stuff explod...
Two Third Level Spells                        • Fireball                         • automatic hit, big damage, stuff explod...
Two Third Level Spells                        • Fireball                         • automatic hit, big damage, stuff explod...
What do spell levels measure?Thursday, July 19, 12power output doesnt work; energy input is just hand waving, no better th...
What do spell levels measure?                                              • power output?Thursday, July 19, 12power outpu...
What do spell levels measure?                                              • power output?                                ...
What do spell levels measure?                                              • power output?                                ...
Moose                                                                      =                                              ...
Moose                                                                      =                                              ...
Problems with L-1 FireballThursday, July 19, 12
Problems with L-1 Fireball                        • now all the first level wizards have fireball                        • b...
Will                         the Fireball                        set metal on                            fire?Thursday, Jul...
Will the                                       Fireball hurt my                                         friends, too?Thurs...
How will                                     Fireball interact                                     with the Charm         ...
Its just a Fireball spell!                              Its not magic!Thursday, July 19, 12(errrr ... you know what I mean!)
Thursday, July 19, 12Well, Perl programmers come upon this really big weird thing, and what do they think? Thisisnt Perl! ...
Ceci nest pas un chameauThursday, July 19, 12Well, Perl programmers come upon this really big weird thing, and what do the...
How will                    Moose interact                     with arrays?Thursday, July 19, 12What? Its just Perl code. ...
Does Moose                          support                        localization?Thursday, July 19, 12Localization of what?...
Can I use                  Moose to write                      SQL?Thursday, July 19, 12I... guess?
Its just a Perl library!                             Its not magic!Thursday, July 19, 12Whether or not this is a contradit...
Ceci nest pas un chameauThursday, July 19, 12So, no matter what sense of weirdness and wonder you might feel at first, just...
Thursday, July 19, 12Moose is just Perl code.
Thursday, July 19, 12Moose is just Perl code.
=Thursday, July 19, 12Moose is just Perl code.
=Thursday, July 19, 12Moose is just Perl code.
=                        Moose is PerlThursday, July 19, 12Moose is just Perl code.
Demystifying MooseThursday, July 19, 12archwizards -- you know, the guys writing Smalltalk and LispThe absolute most impor...
Demystifying Moose                        • youll see a lot of magic-looking featuresThursday, July 19, 12archwizards -- y...
Demystifying Moose                        • youll see a lot of magic-looking features                        • only archwi...
Demystifying Moose                        • youll see a lot of magic-looking features                        • only archwi...
Demystifying Moose                        • youll see a lot of magic-looking features                        • only archwi...
Object-OrientationThursday, July 19, 12
Object-Orientation                          FundamentalsThursday, July 19, 12Yeah, I left out identity. So sue me.People m...
Object-Orientation                            Fundamentals                        • stateThursday, July 19, 12Yeah, I left...
Object-Orientation                            Fundamentals                        • state                        • behavio...
Object-Orientation                            Fundamentals                        • state                        • behavio...
package Employee;      use strict;      use warnings;      sub name_and_title {        my ($self) = @_;               my $...
package Employee;      use strict;      use warnings;      sub name_and_title {        my ($self) = @_;               my $...
Behavior (Methods)      package Employee;      sub name_and_title {        my ($self) = @_;               my $name = $self...
State (Attributes)      package Employee;      sub title {        my $self = shift;               $self->{title} = shift i...
State (Attributes)      package Employee;      sub name {        my $self = shift;               return $self->{name}     ...
package Employee;      sub new {        my ($class, $arg) = @_;               my $self = {                  name => $arg->...
Re-use (Subclassing)      package Employee::Former;      our @ISA = qw(Employee);      sub name_and_title {        my ($se...
package Employee;      use Moose;      has name => (is => ro);      has title => (is => rw);      sub name_and_title {    ...
package Employee;      use Moose;      has name => (is => ro);      has title => (is => rw);      sub name_and_title {    ...
package Employee;      use Moose;      has name => (is => ro);      has title => (is => rw);      sub name_and_title {    ...
use Employee;      my $peon = Employee->new({        name => William Toady,        title => Associate Assistant,      });T...
use Employee;      my $peon = Employee->new({        name => William Toady,        title => Associate Assistant,      }); ...
use Employee;      my $peon = Employee->new({        name => William Toady,        title => Associate Assistant,      }); ...
use Employee;      my $peon = Employee->new({        name => William Toady,        title => Associate Assistant,      }); ...
package Employee;      use Moose;      has name => (is => ro);      has title => (is => rw);      sub name_and_title {    ...
package Employee;      use Moose;      has name => (is => ro);      has title => (is => rw);      sub name_and_title {    ...
package Employee;      use Moose;                              my $employee = Employee->new(...);      has name => (is => ...
package Employee;      use Moose;      use namespace::autoclean;      has name => (is => ro);      has title => (is => rw)...
package Employee::Former;      use Moose;      extends Employee;      sub name_and_title {        my ($self) = @_;        ...
package Employee::Former;      use Moose;      extends Employee;      sub name_and_title {        my ($self) = @_;        ...
package Employee::Former;      use Moose;      extends Employee;      sub name_and_title {        my ($self) = @_;        ...
package Employee::Former;      use Moose;      extends Employee;      override name_and_title => sub {        my ($self) =...
package Employee::Former;      use Moose;      extends Employee;      override name_and_title => sub {        my ($self) =...
package Employee::Former;      use Moose;      extends Employee;      override name_and_title => sub {        my ($self) =...
package Employee::Former;      use Moose;      extends Employee;      override name_and_title => sub {        my ($self) =...
package Employee::Former;      use Moose;      extends Employee;      override name_and_title => sub {        my ($self) =...
package Employee;      use Moose;      has name => (is => ro);      has title => (is => rw);      sub name_and_title {    ...
has name          => (is => ro);      has title => (is => rw);Thursday, July 19, 12"has" is a routine that adds an attribu...
sub title {        my $self = shift;               $self->{title} = shift if @_;               return $self->{title}      ...
has name          => (is => ro);      has title => (is => rw);Thursday, July 19, 12So, we get some pretty nice behavior fr...
has name          => (         reader          => name,      );      has title => (         accessor => title,      );Thur...
has name          => (         reader          => get_name,      );      has title => (         reader  => get_title,     ...
has name          => (         is              => ro,      );      has title => (         is      => rw,      );Thursday, ...
has name          => (         is              => ro,         isa             => Str,      );      has title => (         ...
use Employee;      my $peon = Employee->new({        name => William Toady,        title => Associate Assistant,      });T...
use Employee;      my $peon = Employee->new({        name => [ William, Toady ],        title => Associate Assistant,     ...
Attribute (name) does not pass the type constraint because: Validation failed for      Str with value ARRAY(0x100826a00) a...
Attribute (name) does not pass the type constraint because: Validation failed for      Str with value ARRAY(0x100826a00) a...
Attribute (name) does not pass the type      constraint because: Validation failed for      Str with value ARRAY(0x100826a...
has name          => (         is              => ro,         isa             => Str,      );      has title => (         ...
has name => (         is       => ro,         isa      => Str,         required => 1,      );      has title => (         ...
use Employee;      my $peon = Employee->new({        name => William Toady,      });Thursday, July 19, 12
use Employee;      my $peon = Employee->new({        name => William Toady,      });Thursday, July 19, 12this is key to re...
package Employee::Former;      use Moose;      extends Employee;      override name_and_title => sub { ... };      has +ti...
use Employee::Former;      my $ex_peon = Employee::Former->new({        name => William Toady,      });Thursday, July 19, 12
use Employee::Former;      my $ex_peon = Employee::Former->new({        name => William Toady,      });      $ex_peon->nam...
checkpoint: attributesThursday, July 19, 12
checkpoint: attributes                        • is "ro" and is "rw"Thursday, July 19, 12
checkpoint: attributes                        • is "ro" and is "rw"                        • accessor, reader, writerThurs...
checkpoint: attributes                        • is "ro" and is "rw"                        • accessor, reader, writer     ...
checkpoint: attributes                        • is "ro" and is "rw"                        • accessor, reader, writer     ...
checkpoint: classes and                         subclassesThursday, July 19, 12
checkpoint: classes and                         subclasses                        • use Moose, no Moose                   ...
Set & UnsetThursday, July 19, 12
has name => (         is       => ro,         isa      => Str,         required => 1,      );      has title => (         ...
package Network::Socket;          use Moose;          has port => (             is       => ro,             required => 1,...
package Network::Socket;          use Moose;          has port => (             is       => ro,             required => 1,...
package Network::Socket;          use Moose;          has port => (             is       => ro,             required => 1,...
my %hash      = (             foo =>     1,             bar =>     0,             baz =>     undef,          );Thursday, J...
my %hash      = (             foo =>     1,             bar =>     0,             baz =>     undef,          );          i...
my %hash      = (             foo =>     1,             bar =>     0,             baz =>     undef,          );          i...
my %hash      = (             foo =>     1,             bar =>     0,             baz =>     undef,          );          i...
package Network::Socket;          use Moose;          has port => (             is       => ro,             required => 1,...
package Network::Socket;          use Moose;          has port => (             is      => ro,             isa     => Defi...
package Network::Socket;          use Moose;          has port => (             is       => ro,             isa      => De...
package Network::Socket;          use Moose;          has port => (             is       => ro,             isa      => St...
package Employee;          has expense_acct => (             is => rw             isa => Int,          );Thursday, July 19...
package Employee;          has expense_acct => (             is => rw             isa => Int,          );          if (def...
my $employee = Employee->new({        name => Conrad Veidt,        title => Levity Engineer,        expense_acct => 867530...
my $employee = Employee->new({        name => Conrad Veidt,        title => Levity Engineer,        expense_acct => 867530...
my $employee = Employee->new({        name => Conrad Veidt,        title => Levity Engineer,        expense_acct => 867530...
has expense_acct => (      my $employee = Employee->new({          is => rw        name => Conrad Veidt,          isa => I...
has expense_acct => (      my is => rw Employee->new({          $employee =        name => Int,          isa => Conrad Vei...
has expense_acct => (      my is => rw Employee->new({          $employee =        name => Int,          isa => Conrad Vei...
package Employee;          has expense_acct => (             is => rw             isa => Int,             clearer   => cle...
package Employee;          has expense_acct => (             is => rw             isa => Int,             clearer   => cle...
package Employee;         sub salary {           my ($self) = @_;                  Salary->for_employee( $self );         ...
has _salary => (            is => rw,            isa => Int,            predicate => _has_salary,         );         sub s...
has salary => (            is    => rw,            isa => Int,            default    => sub {               my ($self) = @...
has salary => (            is    => rw,            isa => Int,            lazy => 1,            default    => sub {       ...
has salary => (            is   => rw,            isa => Int,            lazy => 1,            builder => _build_salary,  ...
Thursday, July 19, 12ugh. when we demote him, we want his salary to change!this is extremely easy to solve
my $employee = Employee->new({Thursday, July 19, 12ugh. when we demote him, we want his salary to change!this is extremely...
my $employee = Employee->new({           name => David Niven,Thursday, July 19, 12ugh. when we demote him, we want his sal...
my $employee = Employee->new({           name => David Niven,           title => Managing Director,Thursday, July 19, 12ug...
my $employee = Employee->new({           name => David Niven,           title => Managing Director,         });Thursday, J...
my $employee = Employee->new({           name => David Niven,           title => Managing Director,         });         sa...
my $employee = Employee->new({           name => David Niven,           title => Managing Director,         });         sa...
my $employee = Employee->new({           name => David Niven,           title => Managing Director,         });         sa...
has salary => (            is   => rw,            isa => Int,            lazy => 1,            clearer    => clear_salary,...
sub salary {           my ($self) = @_;                return $self->_salary if $self->_has_salary;                my $sal...
has salary => (            is   => rw,            isa => Int,            lazy => 1,            clearer    => clear_salary,...
has salary => (            is   => rw,            isa => Int,            lazy => 1,            clearer    => clear_salary,...
has salary => (            is   => rw,            isa => Int,            lazy => 1,            clearer    => clear_salary,...
has salary => (         is   => rw,         isa => Int,         lazy => 1,         clearer    => clear_salary,         bui...
has salary => (         is   => ro,         isa => Int,         lazy => 1,         clearer    => clear_salary,         bui...
my $employee = Employee->new({        name   => Ricardo Signes,        title => Research & Development,        salary => 1...
has salary => (         is   => ro,         isa => Int,         lazy => 1,         clearer    => clear_salary,         bui...
has salary => (         is   => ro,         isa => Int,         lazy_build => 1,         init_arg   => yearly_salary,     ...
has salary => (         is   => ro,         isa => Int,         lazy_build => 1,         init_arg   => undef,      );Thurs...
checkpoint: attributes                           unset, build, lazy                        • predicate                    ...
MethodsThursday, July 19, 12
package Network::Socket;      use Moose;      sub send_string {        my ($self, $string) = @_;        ...;      }      s...
package Network::Socket::Noisy;      use Moose;      extends Network::Socket;      override send_string => sub {         m...
package Network::Socket;      use Moose;      sub send_string {        my ($self, $string) = @_;        ...;        return...
package Network::Socket::Noisy;      use Moose;      extends Network::Socket;      override send_string => sub {         m...
package Network::Socket::Noisy;      use Moose;      extends Network::Socket;      override send_string => sub {         m...
override send_lines => sub {        my ($self, $lines) = @_;             my @result = wantarray ? super : scalar super;   ...
after send_lines => sub {        my ($self) = @_;             say $self->describe_client_state;      };Thursday, July 19, ...
after send_string => sub {        my ($self) = @_;             say $self->describe_client_state;      };      after send_l...
after [ send_string, send_lines ] => sub {        my ($self) = @_;             say $self->describe_client_state;      };Th...
after qr/^send_/ => sub {        my ($self) = @_;             say $self->describe_client_state;      };Thursday, July 19, ...
before qr/^send_/ => sub {        my ($self) = @_;             say $self->describe_client_state;      };Thursday, July 19,...
sub send_string {        my ($self, $string) = @_;        ...;        return $reply;      }Thursday, July 19, 12send_strin...
around send_string => sub {        my ($orig, $self, $string) = @_;              say "about to send $string";             ...
around send_string => sub {        my ($orig, $self, $string) = @_;              say "about to send $string";             ...
around send_string => sub {        my ($orig, $self, $string) = @_;              say "about to send $string";             ...
package HTML::Munger;      sub munge_html {        my ($orig, $html_tree) = @_;              # do all kinds of tree-mungin...
package HTML::Munger::Stringy;      use Moose;      extends HTML::Munger;      around munge_html => sub {        my ($orig...
package Employee;      has salary => (         is   => rw,         isa => Int,         lazy => 1,         clearer    => cl...
has salary => (         ...         lazy => 1,      );      has pay_grade => (         ...         lazy => 1,      );     ...
after clear_salary => sub {        my ($self) = @_;               $self->clear_pay_grade;      };Thursday, July 19, 12Afte...
checkpoint:                        method modifiersThursday, July 19, 12
checkpoint:                            method modifiers                        • afterThursday, July 19, 12
checkpoint:                            method modifiers                        • after                        • beforeThurs...
checkpoint:                           method modifiers                        • after                        • before      ...
checkpoint:                             method modifiers                        • after                        • before    ...
checkpoint:                             method modifiers                        • after                        • before    ...
Code ReuseThursday, July 19, 12
Code Reuse with Moose                               Network::Socket                          Network::Socket::NoisyThursda...
Code Reuse with Moose                                   Network::Socket                Network::Socket::Noisy           Ne...
Code Reuse with Moose                                Network::Socket                Network::Socket::Noisy          Networ...
Multiple InheritanceThursday, July 19, 12
Multiple InheritanceThursday, July 19, 12
Multiple Inheritance                        •   Moose supports MIThursday, July 19, 12
Multiple Inheritance                        •   Moose supports MI                        •   method modifiers can          ...
Multiple Inheritance                        •   Moose supports MI                        •   method modifiers can          ...
Multiple Inheritance                        •   Moose supports MI                        •   method modifiers can          ...
Roles!Thursday, July 19, 12Who here has heard about roles?Who has no idea what they are?
Roles in a NutshellThursday, July 19, 12One of the biggest jobs of a role is to act like an #include statement.
Roles in a Nutshell                        #includeThursday, July 19, 12One of the biggest jobs of a role is to act like a...
package Role::Logger;           use Moose::Role;           sub log {             my ($self, $level, $message) = @_;       ...
package Role::Logger;           use Moose::Role;           sub log { ... }           has level => ( ... );           packa...
package Role::Logger;           use Moose::Role;           sub log { ... }           has level => ( ... );           packa...
package Class;           use Moose;           sub log { ... }           has level => ( ... );           sub do_stuff {    ...
package Class;           use Moose;           with Role::Logger;           after log => sub { ... };           sub do_stuf...
package Class;           use Moose;           with Role::Logger;           after log => sub { ... };           has +level ...
package Role::Logger;           use Moose::Role;           sub log {             my ($self, $level, $message) = @_;       ...
package Role::Logger;           use Moose::Role;           requires emit;           sub log {             my ($self, $leve...
package Class;           use Moose;           sub log { ... }           has level => ( ... );           sub do_stuff {    ...
package Class;           use Moose;           die "you forgot emit"             unless __PACKAGE__->can(emit);           s...
package Class;           use Moose;           with Role::Logger;           sub do_stuff {             ...             $sel...
package Class;           use Moose;           with Role::Logger,                Role::Reporter;           sub do_stuff {  ...
package Class;           use Moose;           with Role::Logger,                Role::Reporter,                Role::Socke...
package Class;           use Moose;           with Role::Logger,                Role::Reporter,             # provides "se...
package Class;           with Role::Logger,                Role::Reporter,              # provides "send"                R...
package Class;           with Role::Logger,                Role::Reporter,             # provides "send"                Ro...
package Class;           with Role::Logger,                Role::Reporter,                 # provides "send"              ...
package Class;           with Role::Logger,                Role::Reporter,                 # provides "send"              ...
package Class;     with Role::Logger,          Role::Reporter => {             -alias    => { send => send_report },      ...
#includeThursday, July 19, 12Anyway, now its pretty clear that role composition is more sophisticated than #include, solet...
#include                        • roles can make demandsThursday, July 19, 12Anyway, now its pretty clear that role compos...
#include                        • roles can make demands                        • bits can be excluded or renamedThursday,...
#include                        • roles can make demands                        • bits can be excluded or renamed         ...
#include                        • roles can make demands                        • bits can be excluded or renamed         ...
"Vertical" Code Reuse                        Class                                Subclass->isa(Class)                   S...
"Horizontal" Code Reuse                        Role               Class                         Class->does(Role)Thursday,...
package Network::Socket;          use Moose;          sub send_string { ... }          sub send_lines { ... }Thursday, Jul...
package Network::Socket;          use Moose;          sub send_string { ... }          sub send_lines { ... }          pac...
package Network::Socket;          use Moose;          sub send_string { ... }          sub send_lines { ... }          pac...
package Network::Socket;          use Moose;          sub send_string { ... }          sub send_lines { ... }          pac...
package Network::Socket;          use Moose;          sub send_string { ... }          sub send_lines { ... }          pac...
package Network::Socket;          use Moose;          sub send_string { ... }          sub send_lines { ... }          pac...
package Network::Socket;          use Moose;          with Transmitter;          sub send_string { ... }          sub send...
package Network::Socket;          use Moose;          with Transmitter;          sub send_string { ... }          sub send...
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
A very nice presentation on Moose.
Upcoming SlideShare
Loading in...5
×

A very nice presentation on Moose.

1,970

Published on

A very nice presentation on Moose.

Published in: Education
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,970
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Transcript of "A very nice presentation on Moose."

  1. 1. MO SE o a guide to the new revolutionThursday, July 19, 12
  2. 2. Thursday, July 19, 12
  3. 3. Moose http://rjbs.manxome.org/talks/moose/Thursday, July 19, 12
  4. 4. Any Questions?Thursday, July 19, 12(questions about demographics of the audience)who is using Moose? who knows they want to? who is using what Perl?IS ANYBODY HERE RED/GREEN COLORBLIND?
  5. 5. ???? Moose ????Thursday, July 19, 12
  6. 6. ???? Moose ???? • Moose is the new black •Thursday, July 19, 12
  7. 7. ???? Moose ???? • Moose is the new blackThursday, July 19, 12None of this answers the real question:
  8. 8. ???? Moose ???? • Moose is the new blackThursday, July 19, 12None of this answers the real question:
  9. 9. ???? Moose ???? • Moose is the new black • Moose is at the heart of the new revolutionThursday, July 19, 12None of this answers the real question:
  10. 10. ???? Moose ???? • Moose is the new black • Moose is at the heart of the new revolution • Moose is a game-changing toolThursday, July 19, 12None of this answers the real question:
  11. 11. Thursday, July 19, 12...what is Moose?
  12. 12. MooseThursday, July 19, 12
  13. 13. Moose • Moose is a toolkit for writing classesThursday, July 19, 12
  14. 14. Moose • Moose is a toolkit for writing classes • with some mixin-like featuresThursday, July 19, 12
  15. 15. Moose • Moose is a toolkit for writing classes • with some mixin-like features • and a bunch of parameter validation toolsThursday, July 19, 12
  16. 16. ?????????????????? ?????????????????? ?????????????????? ?????????????????? ?????????????????? ?????????????????? ??????????????????Thursday, July 19, 12Whats so special about that? We have 90,000 of those already!
  17. 17. Perl 5s Object SystemThursday, July 19, 12
  18. 18. Perl 5s Object System • bare bones - a toolkitThursday, July 19, 12
  19. 19. Perl 5s Object System • bare bones - a toolkit • very few assumptionsThursday, July 19, 12
  20. 20. Perl 5s Object System • bare bones - a toolkit • very few assumptions • allows many different strategiesThursday, July 19, 12
  21. 21. Perl 5s Object System • bare bones - a toolkit • very few assumptions • allows many different strategies • this isnt always a featureThursday, July 19, 12
  22. 22. Theres more than one way to do it!Thursday, July 19, 12For example, lets talk about object systems -- since thats what were here to talk about.Almost everybody provides a nice simple way to define classes.
  23. 23. Theres more than one way to do it! ...but sometimes consistency is not a bad thing eitherThursday, July 19, 12For example, lets talk about object systems -- since thats what were here to talk about.Almost everybody provides a nice simple way to define classes.
  24. 24. class Employee attr_accessor :name attr_accessor :title endThursday, July 19, 12Ruby
  25. 25. (defclass Employee () ((Name :accessor Name :initarg :Name) (Title :accessor Title :initarg :Title)))Thursday, July 19, 12Lisp
  26. 26. class Employee { public var $name; public var $title; }Thursday, July 19, 12PHP (!)
  27. 27. class Employee { has Str $.name; has Str $.title; }Thursday, July 19, 12Perl 6
  28. 28. package Employee; sub new { bless {} } for my $attr (qw(name title)) { no strict; *$attr = sub { my $self = shift; $self->{ $attr } = shift if @_; return $self->{ $attr }; }; }Thursday, July 19, 12Perl 5. Ugh.So, Stevan Little was doing some design work on Perl 6, so he kept seeing this...
  29. 29. class Employee { has Str $.name; has Str $.title; }Thursday, July 19, 12and all the associated nice, simple straightforward stuff, and then hed to back to work andsee...
  30. 30. package Employee; sub new { bless {} } for my $attr (qw(name title)) { no strict; *$attr = sub { my $self = shift; $self->{ $attr } = shift if @_; return $self->{ $attr }; }; }Thursday, July 19, 12...this again. So, more or less, he took a bunch of the stuff cooked up by the wizards workingon Perl 6 and translated it into Perl 5, giving us Moose, where we can write this...
  31. 31. package Employee; use Moose; has name => (is => ro); has title => (is => rw);Thursday, July 19, 12Isnt that nice?So, before we get into how Moose works, lets have a quick review of the extreme basics ofOO in Perl... but first:
  32. 32. Thursday, July 19, 12Thats a pretty nice savings. Also, notice the typo in the right-hand side? No. Of course youdidnt!Now, how many people here have played Dungeons and Dragons?
  33. 33. Dungeons & Dragons & MooseThursday, July 19, 12
  34. 34. Jeffs Gameblog http://www.jrients.blogspot.com/Thursday, July 19, 12This is one of my favorite gaming blogs. If you want to know how awesome it is, here is animage that appears on every page: (ig-88)Jeff wrote a really good article about spells and spell levels.
  35. 35. Jeffs Gameblog http://www.jrients.blogspot.com/Thursday, July 19, 12This is one of my favorite gaming blogs. If you want to know how awesome it is, here is animage that appears on every page: (ig-88)Jeff wrote a really good article about spells and spell levels.
  36. 36. Two Third Level SpellsThursday, July 19, 12obviously FB is more powerful! so why is it third level?Jeff wondered the same thing...
  37. 37. Two Third Level Spells • Fireball • automatic hit, big damage, stuff explodesThursday, July 19, 12obviously FB is more powerful! so why is it third level?Jeff wondered the same thing...
  38. 38. Two Third Level Spells • Fireball • automatic hit, big damage, stuff explodes • Flame Arrow • roll to hit, minor damage, BYOB*Thursday, July 19, 12obviously FB is more powerful! so why is it third level?Jeff wondered the same thing...
  39. 39. Two Third Level Spells • Fireball • automatic hit, big damage, stuff explodes • Flame Arrow • roll to hit, minor damage, BYOB* * bring your own bowThursday, July 19, 12obviously FB is more powerful! so why is it third level?Jeff wondered the same thing...
  40. 40. What do spell levels measure?Thursday, July 19, 12power output doesnt work; energy input is just hand waving, no better than the science of Star Trek;he says its because the formula -- the stuff you need to memorize -- is of comparable complexitywhy? because centuries of wizardly research has been done in the field of Fireball and now we know asimple way to cast it; someday maybe well end up with a 1st level fireball -- presumably lots of wizardlyresearchers are working on that right now
  41. 41. What do spell levels measure? • power output?Thursday, July 19, 12power output doesnt work; energy input is just hand waving, no better than the science of Star Trek;he says its because the formula -- the stuff you need to memorize -- is of comparable complexitywhy? because centuries of wizardly research has been done in the field of Fireball and now we know asimple way to cast it; someday maybe well end up with a 1st level fireball -- presumably lots of wizardlyresearchers are working on that right now
  42. 42. What do spell levels measure? • power output? • energy input?Thursday, July 19, 12power output doesnt work; energy input is just hand waving, no better than the science of Star Trek;he says its because the formula -- the stuff you need to memorize -- is of comparable complexitywhy? because centuries of wizardly research has been done in the field of Fireball and now we know asimple way to cast it; someday maybe well end up with a 1st level fireball -- presumably lots of wizardlyresearchers are working on that right now
  43. 43. What do spell levels measure? • power output? • energy input? • formulaic complexity!Thursday, July 19, 12power output doesnt work; energy input is just hand waving, no better than the science of Star Trek;he says its because the formula -- the stuff you need to memorize -- is of comparable complexitywhy? because centuries of wizardly research has been done in the field of Fireball and now we know asimple way to cast it; someday maybe well end up with a 1st level fireball -- presumably lots of wizardlyresearchers are working on that right now
  44. 44. Moose = Level One FireballThursday, July 19, 12Moose gets us a huge number of powerful effects that are just devastating to a lot of menial,boring problems, and the effects are incredibly simple to bring about.
  45. 45. Moose = Level One Fireball Of Object OrientationThursday, July 19, 12Moose gets us a huge number of powerful effects that are just devastating to a lot of menial,boring problems, and the effects are incredibly simple to bring about.
  46. 46. Problems with L-1 FireballThursday, July 19, 12
  47. 47. Problems with L-1 Fireball • now all the first level wizards have fireball • but they still think of it as level 3 spell! • they think its more complex than it is • so they start to think its magicThursday, July 19, 12
  48. 48. Will the Fireball set metal on fire?Thursday, July 19, 12No! Its just fire!
  49. 49. Will the Fireball hurt my friends, too?Thursday, July 19, 12What? Of course! Its a huge ball of fire!
  50. 50. How will Fireball interact with the Charm spell?Thursday, July 19, 12What the hell does that even mean?
  51. 51. Its just a Fireball spell! Its not magic!Thursday, July 19, 12(errrr ... you know what I mean!)
  52. 52. Thursday, July 19, 12Well, Perl programmers come upon this really big weird thing, and what do they think? Thisisnt Perl! This is some other crazy thing.
  53. 53. Ceci nest pas un chameauThursday, July 19, 12Well, Perl programmers come upon this really big weird thing, and what do they think? Thisisnt Perl! This is some other crazy thing.
  54. 54. How will Moose interact with arrays?Thursday, July 19, 12What? Its just Perl code. What?
  55. 55. Does Moose support localization?Thursday, July 19, 12Localization of what? Its just a class building toolkit!
  56. 56. Can I use Moose to write SQL?Thursday, July 19, 12I... guess?
  57. 57. Its just a Perl library! Its not magic!Thursday, July 19, 12Whether or not this is a contradition is left to your judgement.
  58. 58. Ceci nest pas un chameauThursday, July 19, 12So, no matter what sense of weirdness and wonder you might feel at first, just rememberthat...
  59. 59. Thursday, July 19, 12Moose is just Perl code.
  60. 60. Thursday, July 19, 12Moose is just Perl code.
  61. 61. =Thursday, July 19, 12Moose is just Perl code.
  62. 62. =Thursday, July 19, 12Moose is just Perl code.
  63. 63. = Moose is PerlThursday, July 19, 12Moose is just Perl code.
  64. 64. Demystifying MooseThursday, July 19, 12archwizards -- you know, the guys writing Smalltalk and LispThe absolute most important thing I am going to tell you all afternoon is:software is not magic, ever. Its always just software.
  65. 65. Demystifying Moose • youll see a lot of magic-looking featuresThursday, July 19, 12archwizards -- you know, the guys writing Smalltalk and LispThe absolute most important thing I am going to tell you all afternoon is:software is not magic, ever. Its always just software.
  66. 66. Demystifying Moose • youll see a lot of magic-looking features • only archwizards used to get to use themThursday, July 19, 12archwizards -- you know, the guys writing Smalltalk and LispThe absolute most important thing I am going to tell you all afternoon is:software is not magic, ever. Its always just software.
  67. 67. Demystifying Moose • youll see a lot of magic-looking features • only archwizards used to get to use them • but now anybody canThursday, July 19, 12archwizards -- you know, the guys writing Smalltalk and LispThe absolute most important thing I am going to tell you all afternoon is:software is not magic, ever. Its always just software.
  68. 68. Demystifying Moose • youll see a lot of magic-looking features • only archwizards used to get to use them • but now anybody can • and they are not magicThursday, July 19, 12archwizards -- you know, the guys writing Smalltalk and LispThe absolute most important thing I am going to tell you all afternoon is:software is not magic, ever. Its always just software.
  69. 69. Object-OrientationThursday, July 19, 12
  70. 70. Object-Orientation FundamentalsThursday, July 19, 12Yeah, I left out identity. So sue me.People make lots of different lists like this. This isnt necessarily the best one, but its theone that lets me explain Moose pretty well.
  71. 71. Object-Orientation Fundamentals • stateThursday, July 19, 12Yeah, I left out identity. So sue me.People make lots of different lists like this. This isnt necessarily the best one, but its theone that lets me explain Moose pretty well.
  72. 72. Object-Orientation Fundamentals • state • behaviorThursday, July 19, 12Yeah, I left out identity. So sue me.People make lots of different lists like this. This isnt necessarily the best one, but its theone that lets me explain Moose pretty well.
  73. 73. Object-Orientation Fundamentals • state • behavior • code reuseThursday, July 19, 12Yeah, I left out identity. So sue me.People make lots of different lists like this. This isnt necessarily the best one, but its theone that lets me explain Moose pretty well.
  74. 74. package Employee; use strict; use warnings; sub name_and_title { my ($self) = @_; my $name = $self->name; my $title = $self->title; return "$name, $title"; } 1;Thursday, July 19, 12before I start talking about the code here, let me mention a couple of uninteresting hunks ofcode here
  75. 75. package Employee; use strict; use warnings; sub name_and_title { my ($self) = @_; my $name = $self->name; my $title = $self->title; return "$name, $title"; } 1;Thursday, July 19, 12These "use strict" and "use warnings" and "magic true value" are not interesting. I will almostnever show them again, and you should assume that theyre there unless I specifically bring itup.
  76. 76. Behavior (Methods) package Employee; sub name_and_title { my ($self) = @_; my $name = $self->name; my $title = $self->title; return "$name, $title"; }Thursday, July 19, 12behavior! its a method
  77. 77. State (Attributes) package Employee; sub title { my $self = shift; $self->{title} = shift if @_; return $self->{title} }Thursday, July 19, 12weve seen this pattern a bunch of times.what about a read-only attr?
  78. 78. State (Attributes) package Employee; sub name { my $self = shift; return $self->{name} }Thursday, July 19, 12how do we get that name on a new object?
  79. 79. package Employee; sub new { my ($class, $arg) = @_; my $self = { name => $arg->{name}, title => $arg->{title}, }; bless $self => $class; return $self; }Thursday, July 19, 12so, we need some constructor thing
  80. 80. Re-use (Subclassing) package Employee::Former; our @ISA = qw(Employee); sub name_and_title { my ($self) = @_; my $old = $self->SUPER::name_and_title; return "$old (Former)"; }Thursday, July 19, 12re-use! we got all the state and behavior provided by Employee, but with overriddenbehavior for this one method
  81. 81. package Employee; use Moose; has name => (is => ro); has title => (is => rw); sub name_and_title { my ($self) = @_; my $name = $self->name; my $title = $self->title; return "$name, $title"; } no Moose;Thursday, July 19, 12
  82. 82. package Employee; use Moose; has name => (is => ro); has title => (is => rw); sub name_and_title { my ($self) = @_; my $name = $self->name; my $title = $self->title; return "$name, $title"; } no Moose;Thursday, July 19, 12This says, "Hey, Im writing a Moose-based class now."
  83. 83. package Employee; use Moose; has name => (is => ro); has title => (is => rw); sub name_and_title { my ($self) = @_; my $name = $self->name; my $title = $self->title; return "$name, $title"; } no Moose;Thursday, July 19, 12So, we define two attributes. What does that mean?
  84. 84. use Employee; my $peon = Employee->new({ name => William Toady, title => Associate Assistant, });Thursday, July 19, 12First, we get "new" for free.
  85. 85. use Employee; my $peon = Employee->new({ name => William Toady, title => Associate Assistant, }); $peon->title("Assistant to the Associate");Thursday, July 19, 12and we get accessors for our attributes. title is read/write so we can update the object
  86. 86. use Employee; my $peon = Employee->new({ name => William Toady, title => Associate Assistant, }); $peon->title("Assistant to the Associate"); $peon->name("William Riker");Thursday, July 19, 12but name isnt, so when we try this...
  87. 87. use Employee; my $peon = Employee->new({ name => William Toady, title => Associate Assistant, }); $peon->title("Assistant to the Associate"); $peon->name("William Riker");Thursday, July 19, 12it dies
  88. 88. package Employee; use Moose; has name => (is => ro); has title => (is => rw); sub name_and_title { my ($self) = @_; my $name = $self->name; my $title = $self->title; return "$name, $title"; } no Moose;Thursday, July 19, 12Methods look the same.
  89. 89. package Employee; use Moose; has name => (is => ro); has title => (is => rw); sub name_and_title { my ($self) = @_; my $name = $self->name; my $title = $self->title; return "$name, $title"; } no Moose;Thursday, July 19, 12This makes sure that helper functions like "has" arent left around to be accidentally called asmethods later. Ill often skip "no Moose" usually, too. If I show you something and say its aclass, you can probably assume that "no Moose" can be assumed along with the magic truevalue.I dont usually write "no Moose" in my code, anyway. I use a different tool to clean up allthose functions...
  90. 90. package Employee; use Moose; my $employee = Employee->new(...); has name => (is => ro); has title => (is => rw); $employee->has(...); sub name_and_title { my ($self) = @_; my $name = $self->name; my $title = $self->title; return "$name, $title"; } no Moose;Thursday, July 19, 12This makes sure that helper functions like "has" arent left around to be accidentally called asmethods later. Ill often skip "no Moose" usually, too. If I show you something and say its aclass, you can probably assume that "no Moose" can be assumed along with the magic truevalue.I dont usually write "no Moose" in my code, anyway. I use a different tool to clean up allthose functions...
  91. 91. package Employee; use Moose; use namespace::autoclean; has name => (is => ro); has title => (is => rw); sub name_and_title { my ($self) = @_; my $name = $self->name; my $title = $self->title; return "$name, $title"; }Thursday, July 19, 12namespace::autoclean waits until all my code is done compiling, then removes all theroutines that got added by everything else. This cleans up Mooses imports as well as otherhelpers that Ive brought in. Well see why this is so useful later.Anyway, I wont be putting *this* on every slide, either.
  92. 92. package Employee::Former; use Moose; extends Employee; sub name_and_title { my ($self) = @_; my $old = $self->SUPER::name_and_title; return "$old (Former)"; }Thursday, July 19, 12Were makin a subclass now!
  93. 93. package Employee::Former; use Moose; extends Employee; sub name_and_title { my ($self) = @_; my $old = $self->SUPER::name_and_title; return "$old (Former)"; }Thursday, July 19, 12
  94. 94. package Employee::Former; use Moose; extends Employee; sub name_and_title { my ($self) = @_; my $old = $self->SUPER::name_and_title; return "$old (Former)"; }Thursday, July 19, 12and then just the method that calls super -- but I wouldnt really suggest writing this;instead, I would write this...
  95. 95. package Employee::Former; use Moose; extends Employee; override name_and_title => sub { my ($self) = @_; my $old = super; return "$old (Former)"; };Thursday, July 19, 12
  96. 96. package Employee::Former; use Moose; extends Employee; override name_and_title => sub { my ($self) = @_; my $old = super; return "$old (Former)"; };Thursday, July 19, 12Among other things, by doing this, Moose will throw if our superclass has no"name_and_title" method to be overridden, alerting us to stupid mistakes at compile time.
  97. 97. package Employee::Former; use Moose; extends Employee; override name_and_title => sub { my ($self) = @_; my $old = super; return "$old (Former)"; };Thursday, July 19, 12This is prettier than ->SUPER::, but it also helps avoid various weird and annoying bugs. Ifyouve never been bitten by those sorts of bugs, you are lucky!
  98. 98. package Employee::Former; use Moose; extends Employee; override name_and_title => sub { my ($self) = @_; my $old = super; return "$old (Former)"; };Thursday, July 19, 12Since were not making a named sub, were just calling a function. We need to terminate ourstatement. Forgetting that semicolon is a common mistake. I make it daily.
  99. 99. package Employee::Former; use Moose; extends Employee; override name_and_title => sub { my ($self) = @_; my $old = super; return "$old (Former)"; };Thursday, July 19, 12Since were not making a named sub, were just calling a function. We need to terminate ourstatement. Forgetting that semicolon is a common mistake. I make it daily.
  100. 100. package Employee; use Moose; has name => (is => ro); has title => (is => rw); sub name_and_title { my ($self) = @_; my $name = $self->name; my $title = $self->title; return "$name, $title"; }Thursday, July 19, 12
  101. 101. has name => (is => ro); has title => (is => rw);Thursday, July 19, 12"has" is a routine that adds an attribute -- a slot for state -- to our class. we pass it a name(like name or title) and then a hash of options describing the attribute; here, were onlyproviding one option: whether it "is" read-only or read-write"has" doesnt just set up state -- its also setting up behavior, in the method we use to get atthe data. in our super-vanilla implementation, we wrote this:
  102. 102. sub title { my $self = shift; $self->{title} = shift if @_; return $self->{title} } sub name { my $self = shift; return $self->{name} }Thursday, July 19, 12This is what wed shown as read-write and read-only accessors in stock Perl. The version weget from Moose is even better, because it will notice when you try to set a read-only valuelike name and will throw an exception. You could do that in plain ol Perl, too... if youremember.
  103. 103. has name => (is => ro); has title => (is => rw);Thursday, July 19, 12So, we get some pretty nice behavior from just that, and if we want different behavior, we canget it.What we said here is the same as this...
  104. 104. has name => ( reader => name, ); has title => ( accessor => title, );Thursday, July 19, 12"accessor" means that "get or set based on whether I gave you an argument" style that we useall the time in Perlif we wanted something more like Java with get_/set_ we could do this...
  105. 105. has name => ( reader => get_name, ); has title => ( reader => get_title, writer => set_title, );Thursday, July 19, 12What happens is that you still get the same old attributes created, but the methods that relateto them are different. In other words, were changing the behavior associated with theattributes.Moose has lots of ways to let you build behavior based on attributes, and were going to seemore and more of that as we go on.
  106. 106. has name => ( is => ro, ); has title => ( is => rw, );Thursday, July 19, 12but next I want to talk about one more simple way we can describe the potential states of ourobjects: type constraints
  107. 107. has name => ( is => ro, isa => Str, ); has title => ( is => rw, isa => Str, );Thursday, July 19, 12Moose has a type constraint system that lets us define datatypes and constrain attributevalues to them. This is extremely useful...
  108. 108. use Employee; my $peon = Employee->new({ name => William Toady, title => Associate Assistant, });Thursday, July 19, 12...say you meant to do this, but you forgot how name works, and thought it was an arrayrefof first/last name, like you use somewhere else in the code. So you do this:
  109. 109. use Employee; my $peon = Employee->new({ name => [ William, Toady ], title => Associate Assistant, });Thursday, July 19, 12Well, now we know that this is illegal, because we said that name "isa" String. So, as soon aswe try to create this object, we get this exception:
  110. 110. Attribute (name) does not pass the type constraint because: Validation failed for Str with value ARRAY(0x100826a00) at /Users/rjbs/perl5/perlbrew/perls/ perl-5.12.1/lib/site_perl/5.12.1/darwin-2level/Moose/Meta/Attribute.pm line 746 Moose::Meta::Attribute::_coerce_and_verify(Moose::Meta::Attribute=HASH(0x100ac41 48), ARRAY(0x100826a00), Employee=HASH(0x100827270)) called at /Users/rjbs/ perl5/perlbrew/perls/perl-5.12.1/lib/site_perl/5.12.1/darwin-2level/Moose/Meta/ Attribute.pm line 398 Moose::Meta::Attribute::initialize_instance_slot(Moose::Meta::Attribute=HASH(0x1 00ac4148), Moose::Meta::Instance=HASH(0x100ac3bf0), Employee=HASH(0x100827270), HASH(0x100826a18)) called at /Users/rjbs/perl5/ perlbrew/perls/perl-5.12.1/lib/site_perl/5.12.1/darwin-2level/Class/MOP/Class.pm line 567 Class::MOP::Class::_construct_instance(Moose::Meta::Class=HASH(0x100a81538), HASH(0x100826a18)) called at /Users/rjbs/perl5/perlbrew/perls/perl-5.12.1/lib/ site_perl/5.12.1/darwin-2level/Class/MOP/Class.pm line 540 Class::MOP::Class::new_object(Moose::Meta::Class=HASH(0x100a81538), HASH(0x100826a18)) called at /Users/rjbs/perl5/perlbrew/perls/perl-5.12.1/lib/ site_perl/5.12.1/darwin-2level/Moose/Meta/Class.pm line 256 Moose::Meta::Class::new_object(Moose::Meta::Class=HASH(0x100a81538), HASH(0x100826a18)) called at /Users/rjbs/perl5/perlbrew/perls/perl-5.12.1/lib/ site_perl/5.12.1/darwin-2level/Moose/Object.pm line 25 Moose::Object::new(Employee, name, ARRAY(0x100826a00)) called at program.pl line 10Thursday, July 19, 12holy crap! its a gigantic stack trace! get used to it...Moose throws these at the slightest provocation. You will hate them at first and learn to lovethem later. Probably.
  111. 111. Attribute (name) does not pass the type constraint because: Validation failed for Str with value ARRAY(0x100826a00) at /Users/rjbs/perl5/perlbrew/perls/ perl-5.12.1/lib/site_perl/5.12.1/darwin-2level/Moose/Meta/Attribute.pm line 746 Moose::Meta::Attribute::_coerce_and_verify(Moose::Meta::Attribute=HASH(0x100ac41 48), ARRAY(0x100826a00), Employee=HASH(0x100827270)) called at /Users/rjbs/ perl5/perlbrew/perls/perl-5.12.1/lib/site_perl/5.12.1/darwin-2level/Moose/Meta/ Attribute.pm line 398 Moose::Meta::Attribute::initialize_instance_slot(Moose::Meta::Attribute=HASH(0x1 00ac4148), Moose::Meta::Instance=HASH(0x100ac3bf0), Employee=HASH(0x100827270), HASH(0x100826a18)) called at /Users/rjbs/perl5/ perlbrew/perls/perl-5.12.1/lib/site_perl/5.12.1/darwin-2level/Class/MOP/Class.pm line 567 Class::MOP::Class::_construct_instance(Moose::Meta::Class=HASH(0x100a81538), HASH(0x100826a18)) called at /Users/rjbs/perl5/perlbrew/perls/perl-5.12.1/lib/ site_perl/5.12.1/darwin-2level/Class/MOP/Class.pm line 540 Class::MOP::Class::new_object(Moose::Meta::Class=HASH(0x100a81538), HASH(0x100826a18)) called at /Users/rjbs/perl5/perlbrew/perls/perl-5.12.1/lib/ site_perl/5.12.1/darwin-2level/Moose/Meta/Class.pm line 256 Moose::Meta::Class::new_object(Moose::Meta::Class=HASH(0x100a81538), HASH(0x100826a18)) called at /Users/rjbs/perl5/perlbrew/perls/perl-5.12.1/lib/ site_perl/5.12.1/darwin-2level/Moose/Object.pm line 25 Moose::Object::new(Employee, name, ARRAY(0x100826a00)) called at program.pl line 10Thursday, July 19, 12
  112. 112. Attribute (name) does not pass the type constraint because: Validation failed for Str with value ARRAY(0x100826a00) at ... Moose::Object::new(Employee, name, ARRAY(0x100826a00)) called at program.pl line 10Thursday, July 19, 12
  113. 113. has name => ( is => ro, isa => Str, ); has title => ( is => rw, isa => Str, );Thursday, July 19, 12Lets look at one more thing we can do with attributes.
  114. 114. has name => ( is => ro, isa => Str, required => 1, ); has title => ( is => rw, isa => Str, required => 1, );Thursday, July 19, 12now, if you try to create an employee without a title, it will fail.
  115. 115. use Employee; my $peon = Employee->new({ name => William Toady, });Thursday, July 19, 12
  116. 116. use Employee; my $peon = Employee->new({ name => William Toady, });Thursday, July 19, 12this is key to really validating state, and it also lets us show off one last thing.just as we could override method definitions in a subclass, so can we override attributedefinitions
  117. 117. package Employee::Former; use Moose; extends Employee; override name_and_title => sub { ... }; has +title => ( default => Team Member, );Thursday, July 19, 12The + says "were overriding the definition in our superclass. Everything stays the sameexcept for the provided changes."Here, we give a default. If no value is given, the default is used, which lets us satisfy the"required" even when no value was given in the call to the constructor.
  118. 118. use Employee::Former; my $ex_peon = Employee::Former->new({ name => William Toady, });Thursday, July 19, 12
  119. 119. use Employee::Former; my $ex_peon = Employee::Former->new({ name => William Toady, }); $ex_peon->name_and_title; # ===> William Toady, Team Member (former)Thursday, July 19, 12
  120. 120. checkpoint: attributesThursday, July 19, 12
  121. 121. checkpoint: attributes • is "ro" and is "rw"Thursday, July 19, 12
  122. 122. checkpoint: attributes • is "ro" and is "rw" • accessor, reader, writerThursday, July 19, 12
  123. 123. checkpoint: attributes • is "ro" and is "rw" • accessor, reader, writer • isaThursday, July 19, 12
  124. 124. checkpoint: attributes • is "ro" and is "rw" • accessor, reader, writer • isa • requiredThursday, July 19, 12
  125. 125. checkpoint: classes and subclassesThursday, July 19, 12
  126. 126. checkpoint: classes and subclasses • use Moose, no Moose • extends • override • has +attrThursday, July 19, 12
  127. 127. Set & UnsetThursday, July 19, 12
  128. 128. has name => ( is => ro, isa => Str, required => 1, ); has title => ( is => rw, isa => Str, required => 1, );Thursday, July 19, 12"required" means that it must have a value, which brings us to one of the most confusingtopics for beginning Moose users: unset and undefinedto illustrate it, lets imagine a new very simple class
  129. 129. package Network::Socket; use Moose; has port => ( is => ro, required => 1, );Thursday, July 19, 12Remember, in all these slides it isnt "green behaves like we want and red misbehaves" -- its"red code dies and green code lives." Here, we long for death. The green code is badbehavior.
  130. 130. package Network::Socket; use Moose; has port => ( is => ro, required => 1, ); my $socket = Network::Socket->new;Thursday, July 19, 12Remember, in all these slides it isnt "green behaves like we want and red misbehaves" -- its"red code dies and green code lives." Here, we long for death. The green code is badbehavior.
  131. 131. package Network::Socket; use Moose; has port => ( is => ro, required => 1, ); my $socket = Network::Socket->new; my $socket = Network::Socket->new(port => undef);Thursday, July 19, 12Remember, in all these slides it isnt "green behaves like we want and red misbehaves" -- its"red code dies and green code lives." Here, we long for death. The green code is badbehavior.
  132. 132. my %hash = ( foo => 1, bar => 0, baz => undef, );Thursday, July 19, 12
  133. 133. my %hash = ( foo => 1, bar => 0, baz => undef, ); if ( $hash{foo} ) { ... }Thursday, July 19, 12
  134. 134. my %hash = ( foo => 1, bar => 0, baz => undef, ); if ( $hash{foo} ) { ... } if ( defined $hash{bar} ) { ... }Thursday, July 19, 12
  135. 135. my %hash = ( foo => 1, bar => 0, baz => undef, ); if ( $hash{foo} ) { ... } if ( defined $hash{bar} ) { ... } if ( exists $hash{baz} ) { ... }Thursday, July 19, 12
  136. 136. package Network::Socket; use Moose; has port => ( is => ro, required => 1, ); my $socket = Network::Socket->new; my $socket = Network::Socket->new(port => undef);Thursday, July 19, 12so the second one HAS a value -- the value is just undef
  137. 137. package Network::Socket; use Moose; has port => ( is => ro, isa => Defined, ); my $socket = Network::Socket->new; my $socket = Network::Socket->new(port => undef);Thursday, July 19, 12Replacing required with a type of "defined" happily makes the undef fail, but the first onedoesnt -- there is no undefined value given, so we accept it. We need both.
  138. 138. package Network::Socket; use Moose; has port => ( is => ro, isa => Defined, required => 1, ); my $socket = Network::Socket->new; my $socket = Network::Socket->new(port => undef);Thursday, July 19, 12Great! So, now we can really require a value, and a defined one at that. We can do better...
  139. 139. package Network::Socket; use Moose; has port => ( is => ro, isa => Str, required => 1, ); my $socket = Network::Socket->new; my $socket = Network::Socket->new(port => undef);Thursday, July 19, 12...and limit it to a simple scalar!This leads to another bit of confusion, which Ill demonstrate right here.
  140. 140. package Employee; has expense_acct => ( is => rw isa => Int, );Thursday, July 19, 12Were going to add an expense account number to our employees. Some will have them andsome wont. Theyll always be integers.Later on, well want to perform some action based on whether the employee has an account.This is fine, but weve got a problem...
  141. 141. package Employee; has expense_acct => ( is => rw isa => Int, ); if (defined $employee->expense_acct) { ... }Thursday, July 19, 12Were going to add an expense account number to our employees. Some will have them andsome wont. Theyll always be integers.Later on, well want to perform some action based on whether the employee has an account.This is fine, but weve got a problem...
  142. 142. my $employee = Employee->new({ name => Conrad Veidt, title => Levity Engineer, expense_acct => 8675309, });Thursday, July 19, 12Lets say we bring on some high-paid important guy and we issue him an expense accountnumber and he gets to work, and its a total disaster. The stock price plunges, there arethousands of layoffs, and (worst of all) the programmers stop receiving free soda.So, we want to bust this guy down to the very bottom.
  143. 143. my $employee = Employee->new({ name => Conrad Veidt, title => Levity Engineer, expense_acct => 8675309, }); $employee->title(Telephone Sanitizer); $employee->expense_acct( undef );Thursday, July 19, 12We update his title, and we want to kill his expense account.Who can see the problem?
  144. 144. my $employee = Employee->new({ name => Conrad Veidt, title => Levity Engineer, expense_acct => 8675309, }); $employee->title(Telephone Sanitizer); $employee->expense_acct( undef );Thursday, July 19, 12We cant set expense account to undef, because it must be an int.We need the equivalent of delete $hash{key}
  145. 145. has expense_acct => ( my $employee = Employee->new({ is => rw name => Conrad Veidt, isa => Int, title => Levity Engineer, ); expense_acct => 8675309, }); $employee->title(Telephone Sanitizer); $employee->expense_acct( undef );Thursday, July 19, 12We cant set expense account to undef, because it must be an int.We need the equivalent of delete $hash{key}
  146. 146. has expense_acct => ( my is => rw Employee->new({ $employee = name => Int, isa => Conrad Veidt, title => Levity Engineer, clearer => clear_expense_acct, expense_acct => 8675309, ); }); $employee->title(Telephone Sanitizer); $employee->clear_expense_acct;Thursday, July 19, 12
  147. 147. has expense_acct => ( my is => rw Employee->new({ $employee = name => Int, isa => Conrad Veidt, title => Levity Engineer, clearer => clear_expense_acct, expense_acct => 8675309, predicate => has_expense_acct, }); ); $employee->title(Telephone Sanitizer); $employee->clear_expense_acct;Thursday, July 19, 12That predicate is pretty handy -- if the clearer is "delete," the predicate is "exists." Forexample, we might as well use it here...
  148. 148. package Employee; has expense_acct => ( is => rw isa => Int, clearer => clear_expense_acct, predicate => has_expense_acct, );Thursday, July 19, 12the intent is a lot clearer!we can use this for some really really useful stuff, like imagine this...
  149. 149. package Employee; has expense_acct => ( is => rw isa => Int, clearer => clear_expense_acct, predicate => has_expense_acct, ); if ($employee->has_expense_acct) { ... }Thursday, July 19, 12the intent is a lot clearer!we can use this for some really really useful stuff, like imagine this...
  150. 150. package Employee; sub salary { my ($self) = @_; Salary->for_employee( $self ); }Thursday, July 19, 12So, we want a way to compute the employees salary, and its computed by this Salarypackage based on his title, start date, age, interoffice politics, and maybe some other stuff.Its an expensive calculation, so we want to avoid doing it a lot, so we might do this:
  151. 151. has _salary => ( is => rw, isa => Int, predicate => _has_salary, ); sub salary { my ($self) = @_; return $self->_salary if $self->_has_salary; my $salary = Salary->for_employee($self); return $self->_salary($salary); }Thursday, July 19, 12We just make a private attribute -- were using the leading underscore just like we wouldanywhere else in OO perl -- and have our salary method use it as a cache. In other words,we dont compute the value until we need to, and once weve computed it once, we hang onto it. We compute it lazily.This pattern is so useful that its built into Moose.
  152. 152. has salary => ( is => rw, isa => Int, default => sub { my ($self) = @_; return Salary->for_employee( $self ); }, );Thursday, July 19, 12We put the routine for computing the default into a sub as the default value -- we can do thisfor any attribute, by the way, and it gets the object as its argument. This isnt enough,though, because this is going to compute the salary as soon as we make the object. We wantto do it lazily.
  153. 153. has salary => ( is => rw, isa => Int, lazy => 1, default => sub { my ($self) = @_; return Salary->for_employee( $self ); }, );Thursday, July 19, 12so we just tell it to be lazy! now the accessor will generate a default value any time we try toread it while its unset.Note that lazy attributes *require* default values.So whats the next problem?
  154. 154. has salary => ( is => rw, isa => Int, lazy => 1, builder => _build_salary, ); sub _build_salary { my ($self) = @_; return Salary->for_employee( $self ); }Thursday, July 19, 12Im not going to use default, though, Im going to use builder. Its *exactly the same*, but itcalls a method on the object, so you can put your default sub in a separate place, and itseasy to override. Great!So whats the next problem?
  155. 155. Thursday, July 19, 12ugh. when we demote him, we want his salary to change!this is extremely easy to solve
  156. 156. my $employee = Employee->new({Thursday, July 19, 12ugh. when we demote him, we want his salary to change!this is extremely easy to solve
  157. 157. my $employee = Employee->new({ name => David Niven,Thursday, July 19, 12ugh. when we demote him, we want his salary to change!this is extremely easy to solve
  158. 158. my $employee = Employee->new({ name => David Niven, title => Managing Director,Thursday, July 19, 12ugh. when we demote him, we want his salary to change!this is extremely easy to solve
  159. 159. my $employee = Employee->new({ name => David Niven, title => Managing Director, });Thursday, July 19, 12ugh. when we demote him, we want his salary to change!this is extremely easy to solve
  160. 160. my $employee = Employee->new({ name => David Niven, title => Managing Director, }); say $employee->salary; # ==> 500_000Thursday, July 19, 12ugh. when we demote him, we want his salary to change!this is extremely easy to solve
  161. 161. my $employee = Employee->new({ name => David Niven, title => Managing Director, }); say $employee->salary; # ==> 500_000 $employee->title(Pencil Maintenance);Thursday, July 19, 12ugh. when we demote him, we want his salary to change!this is extremely easy to solve
  162. 162. my $employee = Employee->new({ name => David Niven, title => Managing Director, }); say $employee->salary; # ==> 500_000 $employee->title(Pencil Maintenance); say $employee->salary; # ==> 500_000Thursday, July 19, 12ugh. when we demote him, we want his salary to change!this is extremely easy to solve
  163. 163. has salary => ( is => rw, isa => Int, lazy => 1, clearer => clear_salary, builder => _build_salary, );Thursday, July 19, 12We add that clear_salary clearer. Why is this useful? Well, lazy attributes work a lot like Ihacked up, earlier:
  164. 164. sub salary { my ($self) = @_; return $self->_salary if $self->_has_salary; my $salary = Salary->for_employee($self); return $self->_salary($salary); }Thursday, July 19, 12...if we already have a set value, return it; otherwise, calculate it...
  165. 165. has salary => ( is => rw, isa => Int, lazy => 1, clearer => clear_salary, builder => _build_salary, );Thursday, July 19, 12...so if we have a clearer, and we unset the attribute, next time we read it, the builder iscalled again!All that remains is a way to make sure the clearer gets called whenever we need it to be. Thisis easy, too...
  166. 166. has salary => ( is => rw, isa => Int, lazy => 1, clearer => clear_salary, builder => _build_salary, ); has title => ( is => rw, isa => Str, required => 1, );Thursday, July 19, 12heres what we had in our "title" attribute declaration; all we do now is add...
  167. 167. has salary => ( is => rw, isa => Int, lazy => 1, clearer => clear_salary, builder => _build_salary, ); has title => ( is => rw, isa => Str, required => 1, trigger => sub { my ($self) = @_; $self->clear_salary; }, );Thursday, July 19, 12ta daaaaa
  168. 168. has salary => ( is => rw, isa => Int, lazy => 1, clearer => clear_salary, builder => _build_salary, );Thursday, July 19, 12Finally, you see here that weve made salary read/write. We probably want to eliminate theability to directly change the users salary, since we want it to follow our salary-computinglibrarys rules. Part of this is simple...
  169. 169. has salary => ( is => ro, isa => Int, lazy => 1, clearer => clear_salary, builder => _build_salary, );Thursday, July 19, 12...we change the attribute to read-only. Thats a good start, but theres still a way that theuser can set the salary and bypass our algorithm.
  170. 170. my $employee = Employee->new({ name => Ricardo Signes, title => Research & Development, salary => 1_000_000, });Thursday, July 19, 12It can still be specified at construction time! Since there wont be a value set, it wont evercall the getter. How do we avoid this?
  171. 171. has salary => ( is => ro, isa => Int, lazy => 1, clearer => clear_salary, builder => _build_salary, init_arg => salary, );Thursday, July 19, 12Well, theres another "has" argument called init_arg, and it controls the name used toinitialize the attribute in the constructor. By default, its just the attribute name.
  172. 172. has salary => ( is => ro, isa => Int, lazy_build => 1, init_arg => yearly_salary, );Thursday, July 19, 12If we want to change it to something else, we can do that -- this can be useful for offering"public" names for "private" (meaning leading underscore) attributes. But we can also do this:
  173. 173. has salary => ( is => ro, isa => Int, lazy_build => 1, init_arg => undef, );Thursday, July 19, 12Now there is no init_arg for salary, so there is no way to specify it in the constructor.(If specified, it will be ignored, not fatal.)
  174. 174. checkpoint: attributes unset, build, lazy • predicate • clearer • builder • lazy • lazy_buildThursday, July 19, 12Okay! So weve seen a lot about how to produce more powerful behavior centered aroundattributes. Were seeing how Moose makes a lot of pretty powerful, valuable featuresavailable with very little work required -- at least with regard to state. Lets go back totalking about methods again.
  175. 175. MethodsThursday, July 19, 12
  176. 176. package Network::Socket; use Moose; sub send_string { my ($self, $string) = @_; ...; } sub send_lines { my ($self, $lines) = @_; ...; }Thursday, July 19, 12So, were going back to our network socket example. Weve added some methods that welluse to send a hunk of text, or a sequence of lines. All the network code isnt really relevantto this example, so Im leaving it out.Now we want to write a subclass that does a bunch of debugging stuff. Part of that will be toprint out a notice when we send stuff, describing the new client state.
  177. 177. package Network::Socket::Noisy; use Moose; extends Network::Socket; override send_string => sub { my ($self, $string) = @_; my $result = super; say $self->describe_client_state; return $result; }; override send_lines => sub { my ($self, $lines) = @_; my $result = super; say $self->describe_client_state; return $result; };Thursday, July 19, 12So, weve overridden these methods to do the original job, then add this hunk of output --and lets just take describe_client_state as granted -- and then return the result of calling thesuperclass method. So, whats the huge problem weve introduced? (Anybody?)Well, see, I didnt show you the return value of those methods...
  178. 178. package Network::Socket; use Moose; sub send_string { my ($self, $string) = @_; ...; return $reply; } sub send_lines { my ($self, $lines) = @_; ...; return wantarray ? @replies : sum { length } @replies; }Thursday, July 19, 12Ugh! These methods dont all just return a scalar. send_lines might return a list, and nowweve broken any code that relied on the contextual difference in return values
  179. 179. package Network::Socket::Noisy; use Moose; extends Network::Socket; override send_string => sub { my ($self, $string) = @_; my $result = super; say $self->describe_client_state; return $result; }; override send_lines => sub { my ($self, $lines) = @_; my $result = super; say $self->describe_client_state; return $result; };Thursday, July 19, 12We wrote this code...
  180. 180. package Network::Socket::Noisy; use Moose; extends Network::Socket; override send_string => sub { my ($self, $string) = @_; my $result = super; say $self->describe_client_state; return $result; }; override send_lines => sub { my ($self, $lines) = @_; my $result = super; say $self->describe_client_state; return $result; };Thursday, July 19, 12...which forces scalar context on the superclass call, and then returns a scalar no matterwhat.We can try to avoid this in a bunch of ways, but theyre awful. For example, imagine...
  181. 181. override send_lines => sub { my ($self, $lines) = @_; my @result = wantarray ? super : scalar super; say $self->describe_client_state; return wantarray ? @result : $result[0]; };Thursday, July 19, 12Well have to do this in both places, and anyplace else. Its just gross. We dont really want toget in the way of the return value processing, we just want to add some extra behavior to berun after the method. Moose makes this easy.
  182. 182. after send_lines => sub { my ($self) = @_; say $self->describe_client_state; };Thursday, July 19, 12See! Easy! Its so easy that we can just apply the same thing to send_string...
  183. 183. after send_string => sub { my ($self) = @_; say $self->describe_client_state; }; after send_lines => sub { my ($self) = @_; say $self->describe_client_state; };Thursday, July 19, 12And since were modifying that method exactly the same way, we can just say this...
  184. 184. after [ send_string, send_lines ] => sub { my ($self) = @_; say $self->describe_client_state; };Thursday, July 19, 12and if we have a convention for method naming and we just want to apply this modifier toany send_ method, we can write...
  185. 185. after qr/^send_/ => sub { my ($self) = @_; say $self->describe_client_state; };Thursday, July 19, 12Now any superclass method starting with send_ gets this code run after it! We can addmodifiers multiple times, either because were subclassing several levels deep or because wewant two conceptually distinct "after" modifiers on one method. Be careful: if your regexmatches nothing, there is no warning that you might have screwed up.And of course, if we can after, we can also ...
  186. 186. before qr/^send_/ => sub { my ($self) = @_; say $self->describe_client_state; };Thursday, July 19, 12before.there are other modifiers, too. for example...
  187. 187. sub send_string { my ($self, $string) = @_; ...; return $reply; }Thursday, July 19, 12send_string has a nice simple return value, just the string we got back. Lets log what wesend and what we get back -- we cant use before or after for this, because neither can seethe return value. Instead, were going wrap the whole method up with "around"
  188. 188. around send_string => sub { my ($orig, $self, $string) = @_; say "about to send $string"; my $reply = $self->$orig( $string ); say "got $reply in response"; return $reply; };Thursday, July 19, 12So, there are a few things to note here...
  189. 189. around send_string => sub { my ($orig, $self, $string) = @_; say "about to send $string"; my $reply = $self->$orig( $string ); say "got $reply in response"; return $reply; };Thursday, July 19, 12first, we get a reference to the original code before the rest of the normal arguments whenour around "method modifier" is called
  190. 190. around send_string => sub { my ($orig, $self, $string) = @_; say "about to send $string"; my $reply = $self->$orig( $string ); say "got $reply in response"; return $reply; };Thursday, July 19, 12then were responsible for calling the method, doing whatever we want, and returning thereturn value. (this means its up to us to keep track of context, although there are a fewhelpers for that on CPAN; Contextual::Call, for example)the around modifier has a bunch of uses, some obvious or common, and some prettyesoteric. one of the more common uses we see, beyond the "add instrumentation" seenabove, is arg/rv munging
  191. 191. package HTML::Munger; sub munge_html { my ($orig, $html_tree) = @_; # do all kinds of tree-munging stuff to # $html_tree return $new_html_tree; }Thursday, July 19, 12So we have this class that mucks about with HTML::Tree objects, and we like it, but we wantto stop thinking about parsing and re-stringifying our HTML. We just want to deal in strings.So we can write a simple subclass...
  192. 192. package HTML::Munger::Stringy; use Moose; extends HTML::Munger; around munge_html => sub { my ($orig, $self, $html_string) = @_; my $tree = HTML::Tree->parse($html_string); my $new_tree = $self->$orig( $tree ); return $new_tree->as_HTML; };Thursday, July 19, 12and now it expects and returns strings
  193. 193. package Employee; has salary => ( is => rw, isa => Int, lazy => 1, clearer => clear_salary, builder => _build_salary, ); has title => ( ... trigger => sub { my ($self) = @_; $self->clear_salary; }, );Thursday, July 19, 12Okay, one last example of using method modifiers -- and were going to combine them withmethods from attributes!Everybody remember our Employee class? We had to clear the salary when we changed thetitle so that it could be recomputed. What if we have to go the other way?
  194. 194. has salary => ( ... lazy => 1, ); has pay_grade => ( ... lazy => 1, ); sub _build_pay_grade { my ($self) = @_; Salary->pay_grade($self->salary); }Thursday, July 19, 12Now we have the same kind of problem, but in reverse. If we change title, salary gets clearedso it can get re-set. The problem is that we need to clear pay_grade, too, any time we clearthe salary. We cant use a trigger, because triggers arent called on clearing. One again, wecan just use a method modifier.
  195. 195. after clear_salary => sub { my ($self) = @_; $self->clear_pay_grade; };Thursday, July 19, 12After all, even though clear_salary is generated by the "has" statement, its still a method, andwe can modify it with all the method modifiers weve got.
  196. 196. checkpoint: method modifiersThursday, July 19, 12
  197. 197. checkpoint: method modifiers • afterThursday, July 19, 12
  198. 198. checkpoint: method modifiers • after • beforeThursday, July 19, 12
  199. 199. checkpoint: method modifiers • after • before • aroundThursday, July 19, 12
  200. 200. checkpoint: method modifiers • after • before • around • modify [ ... ] => sub { ... }Thursday, July 19, 12
  201. 201. checkpoint: method modifiers • after • before • around • modify [ ... ] => sub { ... } • modify qr/.../ => sub { ... }Thursday, July 19, 12
  202. 202. Code ReuseThursday, July 19, 12
  203. 203. Code Reuse with Moose Network::Socket Network::Socket::NoisyThursday, July 19, 12so, we made a noisy subclass, remember?
  204. 204. Code Reuse with Moose Network::Socket Network::Socket::Noisy Network::Socket::SSLThursday, July 19, 12we also have another subclass, for SSL socketswhat if we want both extensions?
  205. 205. Code Reuse with Moose Network::Socket Network::Socket::Noisy Network::Socket::SSL Network::Socket::Noisy:SSLThursday, July 19, 12The experienced OO programmers are those in the audience who (a) saw this coming and (b)groaned anyway when they saw the slide.
  206. 206. Multiple InheritanceThursday, July 19, 12
  207. 207. Multiple InheritanceThursday, July 19, 12
  208. 208. Multiple Inheritance • Moose supports MIThursday, July 19, 12
  209. 209. Multiple Inheritance • Moose supports MI • method modifiers can make MI less painfulThursday, July 19, 12
  210. 210. Multiple Inheritance • Moose supports MI • method modifiers can make MI less painful • but it doesnt really matterThursday, July 19, 12
  211. 211. Multiple Inheritance • Moose supports MI • method modifiers can make MI less painful • but it doesnt really matter • nobody uses MI in MooseThursday, July 19, 12
  212. 212. Roles!Thursday, July 19, 12Who here has heard about roles?Who has no idea what they are?
  213. 213. Roles in a NutshellThursday, July 19, 12One of the biggest jobs of a role is to act like an #include statement.
  214. 214. Roles in a Nutshell #includeThursday, July 19, 12One of the biggest jobs of a role is to act like an #include statement.
  215. 215. package Role::Logger; use Moose::Role; sub log { my ($self, $level, $message) = @_; return unless $level >= $self->level; say $message; } has level => ( is => rw, isa => Int, default => 0, ); no Moose::Role;Thursday, July 19, 12So, heres a really, really simple role. It looks just like a class, right? Its got attributes andmethods.It isnt a class, though. We cant call new on it, we cant subclass it with "extends," and wecant write a role that is a subclass. Roles are not very classy.
  216. 216. package Role::Logger; use Moose::Role; sub log { ... } has level => ( ... ); package Class; use Moose; sub do_stuff { ... $self->log(5 => "We just did stuff."); }Thursday, July 19, 12So, then we have a class, and we want that class to be able to use our logging code. We actlike weve got that logger method in our class and just go ahead and call it.To get the role composed into our class, we just say...
  217. 217. package Role::Logger; use Moose::Role; sub log { ... } has level => ( ... ); package Class; use Moose; with Role::Logger; sub do_stuff { ... $self->log(5 => "We just did stuff."); }Thursday, July 19, 12the "with" function says, "take this role and use it in my class"what does that mean? well, it means this:
  218. 218. package Class; use Moose; sub log { ... } has level => ( ... ); sub do_stuff { ... $self->log(5 => "We just did stuff."); }Thursday, July 19, 12Everything we said in Role::Logger gets included, right there. Once you have that with, theinclusion happens and everything from there on is normal. So you can go ahead and do stufflike this:
  219. 219. package Class; use Moose; with Role::Logger; after log => sub { ... }; sub do_stuff { ... $self->log(5 => "We just did stuff."); }Thursday, July 19, 12Role::Logger will give us a "log" method, and then we can add some extra "after" behavior.
  220. 220. package Class; use Moose; with Role::Logger; after log => sub { ... }; has +level => (default => 3); sub do_stuff { ... $self->log(5 => "We just did stuff."); }Thursday, July 19, 12...and the same goes for attributes.Theres one more really important kind of thing we can put in a role...
  221. 221. package Role::Logger; use Moose::Role; sub log { my ($self, $level, $message) = @_; return unless $level >= $self->level; $self->emit( $message ); } has level => ( ... ); no Moose::Role;Thursday, July 19, 12Lets say we want this logger role to be able to send to a text file, or STDOUT, or syslog, orwhatever. We replace our old code, which just used say, with a method named emit.We dont want to implement this in the role, though, were going to leave it up to the class,and we note that.
  222. 222. package Role::Logger; use Moose::Role; requires emit; sub log { my ($self, $level, $message) = @_; return unless $level >= $self->level; $self->emit( $message ); } has level => ( ... ); no Moose::Role;Thursday, July 19, 12We just add this "requires" line. It means that "if youre going to use this role, you arerequired to have already implemented this method."Then, when we compose the role...
  223. 223. package Class; use Moose; sub log { ... } has level => ( ... ); sub do_stuff { ... $self->log(5 => "We just did stuff."); }Thursday, July 19, 12Instead of getting just this, we get...
  224. 224. package Class; use Moose; die "you forgot emit" unless __PACKAGE__->can(emit); sub log { ... } has level => ( ... ); sub do_stuff { ... $self->log(5 => "We just did stuff."); }Thursday, July 19, 12Instead of getting just this, we get...
  225. 225. package Class; use Moose; with Role::Logger; sub do_stuff { ... $self->log(5 => "We just did stuff."); }Thursday, July 19, 12We can compose as many roles as we want into our class...
  226. 226. package Class; use Moose; with Role::Logger, Role::Reporter; sub do_stuff { ... $self->log(5 => "We just did stuff."); }Thursday, July 19, 12We can compose as many roles as we want into our class...
  227. 227. package Class; use Moose; with Role::Logger, Role::Reporter, Role::Socket; sub do_stuff { ... $self->log(5 => "We just did stuff."); }Thursday, July 19, 12So, what do these new roles we brought in do? Lets imagine they each provide one method...
  228. 228. package Class; use Moose; with Role::Logger, Role::Reporter, # provides "send" Role::Socket; # provides "send" sub do_stuff { ... $self->log(5 => "We just did stuff."); }Thursday, July 19, 12O no! A method name conflict! Well, what happens? First, lets see what would happen inother systems.
  229. 229. package Class; with Role::Logger, Role::Reporter, # provides "send" Role::Socket; # provides "send" Logger Reporter Socket ClassThursday, July 19, 12With multiple inheritence, I think the problems are pretty well known. Only one of thesewould get called, so we probably have some method to try to disambiguate in our subclass,but its a big hot mess.
  230. 230. package Class; with Role::Logger, Role::Reporter, # provides "send" Role::Socket; # provides "send" Logger Reporter Socket ClassThursday, July 19, 12using mixins, the problems basically remain
  231. 231. package Class; with Role::Logger, Role::Reporter, # provides "send" Role::Socket; # provides "send" Logger Reporter Socket Composite Class RoleThursday, July 19, 12With roles, when we compose multiple roles into one class, Moose first combines all the rolesinto one role. *That* role is the thing we actually include, not each role in any sort of order.The combining process detects any conflict, and if we have conflicting method definitions, itis a compile time failure.
  232. 232. package Class; with Role::Logger, Role::Reporter, # provides "send" Role::Socket; # provides "send" Logger Reporter Socket Composite Class RoleThursday, July 19, 12So, right here, this will fail. We cant have any bizarre runtime behavior because we canteven compile this code.There are ways to resolve this -- we can exclude or rename methods from particular roles,like this...
  233. 233. package Class; with Role::Logger, Role::Reporter => { -alias => { send => send_report }, -excludes => send, }, Role::Socket; # provides "send" Logger Reporter Socket Composite Class RoleThursday, July 19, 12...but this is almost *always* a bad idea, and I promise Ill explain why. Lets not even talkabout doing what this slide shows, though. Just remember: if you see this, its probably adesign problem. In general, if you are doing multiple roles that have conflicting methodnames, it is a sign that you should refactor your classes.
  234. 234. #includeThursday, July 19, 12Anyway, now its pretty clear that role composition is more sophisticated than #include, solets review the waysThat last bit is really important. We know what methods came from where -- but the reallygreat thing is less detailed: we know all the roles that we included in our class.
  235. 235. #include • roles can make demandsThursday, July 19, 12Anyway, now its pretty clear that role composition is more sophisticated than #include, solets review the waysThat last bit is really important. We know what methods came from where -- but the reallygreat thing is less detailed: we know all the roles that we included in our class.
  236. 236. #include • roles can make demands • bits can be excluded or renamedThursday, July 19, 12Anyway, now its pretty clear that role composition is more sophisticated than #include, solets review the waysThat last bit is really important. We know what methods came from where -- but the reallygreat thing is less detailed: we know all the roles that we included in our class.
  237. 237. #include • roles can make demands • bits can be excluded or renamed • were including code, not stringsThursday, July 19, 12Anyway, now its pretty clear that role composition is more sophisticated than #include, solets review the waysThat last bit is really important. We know what methods came from where -- but the reallygreat thing is less detailed: we know all the roles that we included in our class.
  238. 238. #include • roles can make demands • bits can be excluded or renamed • were including code, not strings • we have a record of what was includedThursday, July 19, 12Anyway, now its pretty clear that role composition is more sophisticated than #include, solets review the waysThat last bit is really important. We know what methods came from where -- but the reallygreat thing is less detailed: we know all the roles that we included in our class.
  239. 239. "Vertical" Code Reuse Class Subclass->isa(Class) SubclassThursday, July 19, 12
  240. 240. "Horizontal" Code Reuse Role Class Class->does(Role)Thursday, July 19, 12
  241. 241. package Network::Socket; use Moose; sub send_string { ... } sub send_lines { ... }Thursday, July 19, 12Okay, remember Network::Socket? Now lets imagine we have this Blob class that representsa hunk of data, and we have a method to send it across a network connection, which wellassume is part of Network::Socket.
  242. 242. package Network::Socket; use Moose; sub send_string { ... } sub send_lines { ... } package Blob;Thursday, July 19, 12Okay, remember Network::Socket? Now lets imagine we have this Blob class that representsa hunk of data, and we have a method to send it across a network connection, which wellassume is part of Network::Socket.
  243. 243. package Network::Socket; use Moose; sub send_string { ... } sub send_lines { ... } package Blob; sub send_to { my ($self, $target) = @_; confess "cant send to $target" unless $target->isa(Network::Socket); $target->send_string( $self->contents ); }Thursday, July 19, 12So, were going to do a little input validation, and traditionally the way to check for aninterface is to use "isa" which we do right here...
  244. 244. package Network::Socket; use Moose; sub send_string { ... } sub send_lines { ... } package Blob; sub send_to { my ($self, $target) = @_; confess "cant send to $target" unless $target->isa(Network::Socket); $target->send_string( $self->contents ); }Thursday, July 19, 12Of course, the problem is that now if we want to write some other kind of valid target for theBlob to send to, it has to subclass Network::Socket, which has a zillion methods, attributes,and all kinds of assumptions. Anybody maintaining Blob will think they can rely on any ofthose, and we dont want to encourage that. One option would be to say...
  245. 245. package Network::Socket; use Moose; sub send_string { ... } sub send_lines { ... } package Blob; sub send_to { my ($self, $target) = @_; confess "cant send to $target" unless $target->can(send_string); $target->send_string( $self->contents ); }Thursday, July 19, 12...and thats a lot better, but we can do better. For one thing, how do we know it has theright semantics for that method? What if its a coincidence?Obviously were getting at roles, right? Right. Its easy...
  246. 246. package Network::Socket; use Moose; sub send_string { ... } sub send_lines { ... } package Blob; sub send_to { my ($self, $target) = @_; confess "cant send to $target" unless $target->does(Transmitter); $target->send_string( $self->contents ); }Thursday, July 19, 12We just require that Network::Socket "does" the Transmitter role. Whats that role look like?
  247. 247. package Network::Socket; use Moose; with Transmitter; sub send_string { ... } sub send_lines { ... } package Transmitter; use Moose::Role; requires send_string;Thursday, July 19, 12Seriously, thats it. Thats all. Here, were not using roles to act like an #include of code,were using it because it can act as a contract: by including Transmitter, the author ofNetwork::Socket promised to implement send_string. Moose makes sure he keeps hispromise and lets us know by, well, not *dying*.
  248. 248. package Network::Socket; use Moose; with Transmitter; sub send_string { ... } sub send_lines { ... } package Transmitter; use Moose::Role; requires send_string;Thursday, July 19, 12So, roles are going to serve us in two ways: theyre going to let us re-use bundles offeatures, and theyre going to let us check that classes or objects provide well-known,promised bundles of features.

×