3. OO Perl with Moose
What is Moose?
Moose is a postmodern object system for Perl 5 that takes
the tedium out of writing object-oriented Perl. It borrows all
the best features from Perl 6, CLOS (LISP), Smalltalk, Java,
BETA, OCaml, Ruby and more, while still keeping true to its
Perl 5 roots.
5. OO Perl with Moose
Why Moose?
makes Perl 5 OO both simpler and more powerful
6. OO Perl with Moose
Why Moose?
makes Perl 5 OO both simpler and more powerful
define your class declaratively
7. OO Perl with Moose
Why Moose?
makes Perl 5 OO both simpler and more powerful
define your class declaratively
offers "sugar" for object construction, attributes, e.t.c
8. OO Perl with Moose
Why Moose?
makes Perl 5 OO both simpler and more powerful
define your class declaratively
offers "sugar" for object construction, attributes, e.t.c
don't need to care how they are implemented
9. OO Perl with Moose
Why Moose?
makes Perl 5 OO both simpler and more powerful
define your class declaratively
offers "sugar" for object construction, attributes, e.t.c
don't need to care how they are implemented
concentrate on the logical structure of your classes
10. OO Perl with Moose
Why Moose?
makes Perl 5 OO both simpler and more powerful
define your class declaratively
offers "sugar" for object construction, attributes, e.t.c
don't need to care how they are implemented
concentrate on the logical structure of your classes
don't need to be a wizard to use it
11. OO Perl with Moose
Why Moose?
makes Perl 5 OO both simpler and more powerful
define your class declaratively
offers "sugar" for object construction, attributes, e.t.c
don't need to care how they are implemented
concentrate on the logical structure of your classes
don't need to be a wizard to use it
but if you are, lets you dig about in the guts and extend it
12. OO Perl with Moose
package Person; To make a class you start
1;
with a package
13. OO Perl with Moose
package Person; To make a class you start
use Moose;
with a package and just use
1; Moose
14. OO Perl with Moose
package Person; This is a complete class
use Moose;
definition
1;
15. OO Perl with Moose
package Person; This is a complete class
use Moose;
definition
1;
not terribly useful though
16. OO Perl with Moose
package Person; Under the hood Moose is
use Moose;
doing a lot
1;
17. OO Perl with Moose
package Person; Under the hood Moose is
use Moose;
doing a lot
1;
(won't go into that though)
18. OO Perl with Moose
package Person; Classes have zero or more
use Moose;
attributes
1;
19. OO Perl with Moose
package Person; Attributes are declared using
use Moose;
the has function
has 'birth_date' => (
);
1;
20. OO Perl with Moose
package Person; Attributes are declared using
use Moose;
the has function
has 'birth_date' => (
); Attributes have properties
1;
21. OO Perl with Moose
package Person; Attributes are declared using
use Moose;
the has function
has 'birth_date' => (
); Attributes have properties
1;
probably the most powerful
feature of Moose
22. OO Perl with Moose
package Person; Can be provided with
use Moose;
accessors
has 'birth_date' => (
);
1;
23. OO Perl with Moose
package Person; Can be provided with
use Moose;
accessors by stating that
has 'birth_date' => ( attribute is read-writeable
is => 'rw',
);
1;
24. OO Perl with Moose
package Person; or read-only
use Moose;
has 'birth_date' => (
is => 'ro',
);
1;
25. OO Perl with Moose
package Person; or you can provide your own
use Moose;
reader and/or writer
has 'birth_date' => (
is => 'ro',
writer => '_set_birth_date',
);
1;
26. OO Perl with Moose
package Person; You can specify a type for
use Moose;
your attribute
has 'birth_date' => (
is => 'ro',
isa => 'Str',
);
1;
27. OO Perl with Moose
package Person; Only values that pass the
use Moose;
type check will be accepted
has 'birth_date' => ( for the attribute
is => 'ro',
isa => 'Str',
);
1;
28. OO Perl with Moose
package Person; Built in types include:
use Moose;
Str
has 'birth_date' => ( Num
is => 'ro', ArrayRef
isa => 'Str', CodeRef
);
Any
1; more ...
29. OO Perl with Moose
package Person; Class names are treated as
use Moose;
use DateTime;
types
has 'birth_date' => (
is => 'ro',
isa => 'DateTime',
);
1;
30. OO Perl with Moose
package Person;
use Moose; You can create your own
use Moose::Util::TypeConstraints; types
use DateTime;
subtype 'ModernDateTime'
has 'birth_date' => (
is => 'ro',
isa => 'DateTime',
);
1;
31. OO Perl with Moose
package Person;
use Moose; You can create your own
use Moose::Util::TypeConstraints; types
use DateTime;
from existing types
subtype 'ModernDateTime'
=> as 'DateTime'
has 'birth_date' => (
is => 'ro',
isa => 'DateTime',
);
1;
32. OO Perl with Moose
package Person;
use Moose; You can create your own
use Moose::Util::TypeConstraints; types
use DateTime;
from existing types
subtype 'ModernDateTime'
=> as 'DateTime'
=> where { $_->year >= 2000 }; and apply your own
constraints on them
has 'birth_date' => (
is => 'ro',
isa => 'DateTime',
);
1;
33. OO Perl with Moose
package Person;
use Moose; You can create your own
use Moose::Util::TypeConstraints; types
use DateTime;
from existing types
subtype 'ModernDateTime'
=> as 'DateTime'
=> where { $_->year >= 2000 };and apply your own
constraints on them
has 'birth_date' => (
is => 'ro',
isa => 'ModernDateTime', and use them
);
1;
34. OO Perl with Moose
package Person;
use Moose; You can also coerce one
use Moose::Util::TypeConstraints; type into another
use DateTime;
subtype 'ModernDateTime'
=> as 'DateTime'
=> where { $_->year >= 2000 };
has 'birth_date' => (
is => 'ro',
isa => 'ModernDateTime',
);
1;
35. OO Perl with Moose
package Person;
use Moose; See Moose::Manual::Types
use Moose::Util::TypeConstraints; for more details
use DateTime;
subtype 'ModernDateTime'
=> as 'DateTime'
=> where { $_->year >= 2000 };
has 'birth_date' => (
is => 'ro',
isa => 'ModernDateTime',
);
1;
36. OO Perl with Moose
package Person;
use Moose; A person with no birth date
use Moose::Util::TypeConstraints; seems odd
use DateTime;
subtype 'ModernDateTime'
=> as 'DateTime'
=> where { $_->year >= 2000 };
has 'birth_date' => (
is => 'ro',
isa => 'ModernDateTime',
);
1;
37. OO Perl with Moose
package Person;
use Moose; A person with no birth date
use Moose::Util::TypeConstraints; seems odd
use DateTime;
so it can be made
subtype 'ModernDateTime'
=> as 'DateTime' compulsary with the
=> where { $_->year >= 2000 };required flag
has 'birth_date' => (
is => 'ro',
isa => 'ModernDateTime',
required => 1,
);
1;
38. OO Perl with Moose
package Person;
use Moose; You can also set default
use Moose::Util::TypeConstraints; values for the attribute
use DateTime;
subtype 'ModernDateTime'
=> as 'DateTime'
=> where { $_->year >= 2000 };
has 'birth_date' => (
is => 'ro',
isa => 'ModernDateTime',
required => 1,
default => '2000-01-01',
);
1;
39. OO Perl with Moose
package Person;
use Moose; Complex defaults need to
use Moose::Util::TypeConstraints; be set in a sub ref
use DateTime;
subtype 'ModernDateTime'
=> as 'DateTime'
=> where { $_->year >= 2000 };
has 'birth_date' => (
is => 'ro',
isa => 'ModernDateTime',
required => 1,
default => sub { DateTime->now },
);
1;
40. OO Perl with Moose
package Person;
use Moose; or you could write a
separate builder method
# subtype ...
has 'birth_date' => (
is => 'ro',
isa => 'ModernDateTime',
required => 1,
builder => '_build_birth_date',
);
sub _build_birth_date {
DateTime->now;
}
1;
41. OO Perl with Moose
package Person;
use Moose; and make it lazy
# subtype ...
has 'birth_date' => (
is => 'ro',
isa => 'ModernDateTime',
required => 1,
builder => '_build_birth_date',
lazy => 1,
);
sub _build_birth_date {
DateTime->now;
}
1;
42. OO Perl with Moose
package Person;
use Moose; or in one step
# subtype ...
has 'birth_date' => (
is => 'ro',
isa => 'ModernDateTime',
required => 1,
lazy_build => 1,
);
sub _build_birth_date {
DateTime->now;
}
1;
43. OO Perl with Moose
package Person;
use Moose; Attributes handle
delegation
# subtype ...
has 'birth_date' => (
is => 'ro',
isa => 'ModernDateTime',
required => 1,
lazy_build => 1,
handles => { birth_year => 'year' },
);
sub _build_birth_date {
DateTime->now;
}
1;
44. OO Perl with Moose
package Person;
use Moose; Attributes handle
delegation
# subtype ...
has 'birth_date' => ( Calling $person-
is => 'ro',
isa => 'ModernDateTime', >birth_year delegates to
required => 1, $person->birth_date->year
lazy_build => 1,
handles => { birth_year => 'year' },
);
sub _build_birth_date {
DateTime->now;
}
1;
45. OO Perl with Moose
package Person;
use Moose; Delegation is one option to
inheritance
# subtype ...
has 'birth_date' => (
is => 'ro',
isa => 'ModernDateTime',
required => 1,
lazy_build => 1,
handles => { birth_year => 'year' },
);
sub _build_birth_date {
DateTime->now;
}
1;
46. OO Perl with Moose
package Person;
use Moose; Delegation is one option to
inheritance
# subtype ...
has 'birth_date' => ( Especially when inheriting
is => 'ro',
isa => 'ModernDateTime', from non-Moose based
required => 1, classes
lazy_build => 1,
handles => { birth_year => 'year' },
);
sub _build_birth_date {
DateTime->now;
}
1;
47. OO Perl with Moose
package Employee; Inheritance is achieved with
use Moose;
extends qw( Person );
the extends function
1;
48. OO Perl with Moose
package Employee; Inheritance is achieved with
use Moose;
extends qw( Person );
the extends function
1; Moose supports multiple
inheritance
49. OO Perl with Moose
package Employee; Inheritance is achieved with
use Moose;
extends qw( Person );
the extends function
1; Moose supports multiple
inheritance just pass more
class names to extends
50. OO Perl with Moose
package Employee; Override parent methods with
use Moose;
extends qw( Person );
the override function
override '_build_birth_date' => sub {
# ...
}
1;
51. OO Perl with Moose
package Employee; Call the parent method with
use Moose;
extends qw( Person );
the super function
override '_build_birth_date' => sub {
# ...
super();
}
1;
52. OO Perl with Moose
package Employee; You can also override
use Moose;
extends qw( Person );
attributes
has '+birth_date' => (
# ...
);
1;
53. OO Perl with Moose
package Employee; You can also override
use Moose;
extends qw( Person );
attributes (carefully)
has '+birth_date' => (
# ...
);
1;
54. OO Perl with Moose
package Science; Moose also has a concept of
1;
roles
55. OO Perl with Moose
package Science; Moose also has a concept of
use Moose::Role;
roles
1;
Declared by using Moose::
Role
56. OO Perl with Moose
package Science; Similar to Smalltalk traits,
use Moose::Role;
Ruby Mixins and Java
1; interfaces
57. OO Perl with Moose
package Science; Similar to Smalltalk traits,
use Moose::Role;
Ruby Mixins and Java
1; interfaces
Most similar to Perl 6 Roles
58. OO Perl with Moose
package Science; A collection of reusable traits
use Moose::Role;
(attributes)
1;
59. OO Perl with Moose
package Science; A collection of reusable traits
use Moose::Role;
(attributes)
has 'speciality' => (
# ...
);
1;
60. OO Perl with Moose
package Science; A collection of reusable traits
use Moose::Role;
(attributes) and behaviour
has 'speciality' => ( (methods)
# ...
);
sub research {
# ...
}
1;
61. OO Perl with Moose
package Science; Roles are not classes
use Moose::Role;
has 'speciality' => (
# ...
);
sub research {
# ...
}
1;
62. OO Perl with Moose
package Science; Roles are not classes
use Moose::Role;
has 'speciality' => ( cannot instantiate a role
# ...
);
sub research {
# ...
}
1;
63. OO Perl with Moose
package Science; Roles are not classes
use Moose::Role;
has 'speciality' => ( cannot instantiate a role
# ... cannot inherit from a role
);
sub research {
# ...
}
1;
64. OO Perl with Moose
package Science; Roles are another option to
use Moose::Role;
inheritance
has 'speciality' => (
# ...
);
sub research {
# ...
}
1;
65. OO Perl with Moose
package Science; Roles are composed into
use Moose::Role;
consuming classes/roles
has 'speciality' => (
# ...
);
sub research {
# ...
}
1;
66. OO Perl with Moose
package Science; Roles are composed into
use Moose::Role;
consuming classes/roles
has 'speciality' => (
# ... Attributes and methods from
); role are flattened into
sub research { consuming class/role
# ...
}
1;
67. OO Perl with Moose
package Science; Roles can insist that
use Moose::Role;
consuming classes
has 'speciality' => ( implement certain methods
# ...
);
sub research {
# ...
}
1;
68. OO Perl with Moose
package Science; Roles can insist that
use Moose::Role;
consuming classes
requires qw( research ); implement certain methods
has 'speciality' => (
# ... Use the requires function
);
1;
69. OO Perl with Moose
package Science; Roles can insist that
use Moose::Role;
consuming classes
requires qw( research ); implement certain methods
has 'speciality' => (
# ... Use the requires function
);
1;
Consuming classes must
now implement the research
function
70. OO Perl with Moose
package Scientist; Roles are consumed into
use Moose;
extends qw( Person );
classes by using the with
with qw( Science ); keyword
sub research { ... }
1;
71. OO Perl with Moose
package Scientist; Roles are consumed into
use Moose;
extends qw( Person );
classes by using the with
with qw( Science ); keyword
sub research { ... } More than one role can be
1;
consumed into a class
72. OO Perl with Moose
package Scientist; Roles are consumed into
use Moose;
extends qw( Person );
classes by using the with
with qw( Science ); keyword
sub research { ... } More than one role can be
1;
consumed into a class just
pass more roles to with
73. OO Perl with Moose
package Scientist; Class methods and attributes
use Moose;
extends qw( Person );
are prioritized
with qw( Science );
sub research { ... }
1;
74. OO Perl with Moose
package Scientist; Class methods and attributes
use Moose;
extends qw( Person );
are prioritized
with qw( Science );
Conflicts are resolved at
sub research { ... } compile time
1;
75. OO Perl with Moose
package Scientist; See Moose::Manual::Roles
use Moose;
extends qw( Person );
for details
with qw( Science );
sub research { ... }
1;
76. OO Perl with Moose
package Scientist; Moose is not perfect
use Moose;
extends qw( Person );
with qw( Science );
sub research { ... }
1;
77. OO Perl with Moose
package Scientist; Moose is not perfect
use Moose;
extends qw( Person );
with qw( Science ); Biggest caveat is start up
time
sub research { ... }
1;
78. OO Perl with Moose
package Scientist; Moose is not perfect
use Moose;
extends qw( Person );
with qw( Science ); Biggest caveat is start up
time
sub research { ... }
1;
Actively being worked on
79. OO Perl with Moose
package Scientist; Moose is not perfect
use Moose;
extends qw( Person );
with qw( Science ); Biggest caveat is start up
time
sub research { ... }
1;
Actively being worked on
But you can help
80. OO Perl with Moose
package Scientist;
use Moose; Make your classes immutable
extends qw( Person );
with qw( Science );
sub research { ... }
__PACKAGE__->meta->make_immutable();
1;
81. OO Perl with Moose
package Scientist;
use Moose; Make your classes immutable
extends qw( Person );
with qw( Science ); This lets Moose create an
inline constructor for your
sub research { ... }
class
__PACKAGE__->meta->make_immutable();
1;
82. OO Perl with Moose
package Scientist;
use Moose; Make your classes immutable
extends qw( Person );
with qw( Science ); This lets Moose create an
inline constructor for your
sub research { ... }
class
__PACKAGE__->meta->make_immutable();
1;
Greatly speeding up start up
time
83. OO Perl with Moose
package Scientist;
use Moose; Also you are adviced to clean
extends qw( Person ); up after your class
with qw( Science );
i.e remove all Moose sugar
sub research { ... }
__PACKAGE__ from packages using your
->meta->make_immutable(); classes
1;
84. OO Perl with Moose
package Scientist;
use Moose; Also you are adviced to clean
extends qw( Person ); up after your class
with qw( Science );
i.e remove all Moose sugar
sub research { ... }
__PACKAGE__ from packages using your
->meta->make_immutable(); classes
no Moose;
1;
85. OO Perl with Moose
package Scientist;
use Moose; Also you are adviced to clean
use namespace::clean up after your class
-except => [qw( meta )];
extends qw( Person ); i.e remove all Moose sugar
with qw( Science );
from packages using your
sub research { ... } classes
__PACKAGE__
->meta->make_immutable();
1;
Alternatively
87. OO Perl with Moose
Moose is also extensible
Done by manipulating metaclass objects
88. OO Perl with Moose
Moose is also extensible
Done by manipulating metaclass objects
This is where the wizards roam free
89. OO Perl with Moose
Moose is also extensible
Done by manipulating metaclass objects
This is where the wizards roam free
A lot of extensions exist in the MooseX:: namespace
90. OO Perl with Moose
Moose is also extensible
Done by manipulating metaclass objects
This is where the wizards roam free
A lot of extensions exist in the MooseX:: namespace
New ideas usually start life here
91. OO Perl with Moose
Moose is also extensible
Done by manipulating metaclass objects
This is where the wizards roam free
A lot of extensions exist in the MooseX:: namespace
New ideas usually start life here
Good ones get incorporated into Moose
92. OO Perl with Moose
Moose is also extensible
Done by manipulating metaclass objects
This is where the wizards roam free
A lot of extensions exist in the MooseX:: namespace
New ideas usually start life here
Good ones get incorporated into Moose
An example is MooseX::AttributeHelpers
93. OO Perl with Moose
Moose is also extensible
Done by manipulating metaclass objects
This is where the wizards roam free
A lot of extensions exist in the MooseX:: namespace
New ideas usually start life here
Good ones get incorporated into Moose
An example is MooseX::AttributeHelpers
These were incorporated in the Moose::Meta::Attribute::
Native namespace
94. OO Perl with Moose
package Person;
use Moose; Lastly you will note that
use namespace::clean Moose introduces its own
-except => [qw( meta )]; boiler plate code
# attributes and methods
__PACKAGE__->meta->make_immutable();
1;
95. OO Perl with Moose
package Person;
use Moose; Lastly you will note that
use namespace::clean Moose introduces its own
-except => [qw( meta )]; boiler plate code
# attributes and methods
__PACKAGE__->meta->make_immutable(); is an extension
There that
1; reduces this
96. OO Perl with Moose
package Person;
use Moose; Lastly you will note that
use namespace::clean Moose introduces its own
-except => [qw( meta )]; boiler plate code
# attributes and methods
__PACKAGE__->meta->make_immutable(); is an extension
There that
1; reduces this
MooseX::Declare
97. OO Perl with Moose
use MooseX::Declare;
Declaring classes becomes
class Person { even more declarative
# attributes and methods
}
98. OO Perl with Moose
use MooseX::Declare;
Combines the power of
class Person { Moose with Devel::Declare to
# attributes and methods produce keywords for Perl 5
} written in Perl 5
99. OO Perl with Moose
use MooseX::Declare;
Combines the power of
class Person { Moose with Devel::Declare to
# attributes and methods produce keywords for Perl 5
method research() { ... } written in Perl 5
}
Keywords include class, role,
method
100. OO Perl with Moose
use MooseX::Declare;
Combines the power of
class Person { Moose with Devel::Declare to
# attributes and methods produce keywords for Perl 5
method research() { ... } written in Perl 5
}
Keywords include class, role,
method
Note that the methods have
signatures complete with type
checking
101. OO Perl with Moose
use MooseX::Declare;
Combines the power of
class Person { Moose with Devel::Declare to
# attributes and methods produce keywords for Perl 5
method research() { ... } written in Perl 5
}
Keywords include class, role,
method
Note that the methods have
signatures complete with type
checking
So using MooseX::Declare the Scientist class example could look
like the following:
102. OO Perl with Moose
use MooseX::Declare;
class Scientist extends Person with Science {
use Duration; # fictional class one could write
has 'funding' => (
is => 'rw',
isa => 'Num',
lazy_build => 1,
);
method research( Duration $contract_duration ) {
unless ( $self->has_funding ) {
confess 'need funding to work';
}
while ( not $contract_duration->expired ) {
# do your research ...
}
}
}