Moose: A Postmodern Object System for Perl Stuart Skelton.
-
Upload
kenneth-andrews -
Category
Documents
-
view
217 -
download
0
Transcript of Moose: A Postmodern Object System for Perl Stuart Skelton.
Moose:A Postmodern Object System
for Perl
Stuart Skelton
2
What is OOP?
“Traditional” programming is procedural Subroutines work on variables my $distance = distance($point1,$point2); Variables are dumb Just stores for data
3
What is OOP?
Object Oriented programming inverts this Variables are objects Objects can carry out certain processes
Called methods my $distance = $point1->distance($point2);
Objects are intelligent Objects know what methods they can carry
out
4
Some Concepts
A Class is a type of intelligent variable (blueprint of an object) e.g. Dog
An Object is an instance of a class e.g. Amber
An Attribute is a piece of data in an object e.g. KennelClubName
A Method is an action that an object does e.g. Bark
5
Methods
Methods can be either class methods or object methods
Class methods are called on a class my $amber = Dog->new;
Object methods are called on an object $amber->bark;
6
Constructors
All classes need a constructor method Creates a new object of that class Usually a class method Often called new my $amber = Dog->new; my $hunter = new Dog;
7
Accessors & Mutators
Access object attributes with an accessor method
say “The kennel club name of Amber is “,$amber->get_kennel_club_name;
Change an attribute with a mutator method $amber->set_age( $amber->get_age + 1);
8
Accessor & Mutators
Accessors and mutators are often the same method
say “The kennel club name of Amber is “, $amber->kennel_club_name;
$amber->age($amber->age + 1);
Checks number of parameters Reacts appropriately
9
Traditional Perl OOP
10
Basic Anatomy
Package Classname;
atribute1
attribute2
method1
method2
1;
package PointTP;
sub new{ my $class = shift; my $self = { x => shift, y => shift, }; bless $self, $class; return $self;}
sub set_x { my ( $self, $x ) = @_; $self->{x} = $x if defined($x);}sub get_x { my( $self ) = @_; return $self->{x};}sub set_y { my ( $self, $y ) = @_; $self->{y} = $y if defined($y);}sub get_y { my( $self ) = @_; return $self->{y};}
#!/usr/bin/perl
use Modern::Perl ;
use PointTP ;
my $point1 = Point->new(1,2) ;
say $point1->get_x() ; # prints 1
#change the x-coord
$point1->set_x(-10);
say $point1->get_x() ; # prints -10
sub set_x {
my ( $self, $x ) = @_;
$self->{x} = $x if defined($x);
}
sub get_x {
my( $self ) = @_;
return $self->{x};
} sub x { my ($self, $new_x) = @_;
if (defined $new_x) { $self->{x} = $new_x; }
return $self->{x};}
#!/usr/bin/perl
use Modern::Perl ;
use Point ;
my $point1 = Point->new(1,2) ;
say $point1->x() ; # prints 1
#change the x-coord
$point1->x(-10);
say $point1->x() ; # prints -10
Moose
16
Moose
Moose is a Modern Object System for Perl 5 Based on Perl 6 object system More powerful More flexible Easier
17
Simple Moose Classpackage Point;use Moose;
has x => ( is => 'rw', isa => 'Num', required => 1);has y => ( is => 'rw', isa => 'Num', required => 1);
no Moose;__PACKAGE__->meta->make_immutable;
18
What's Going On?
use Moose; Loads Moose environment Makes our class a subclass of Moose::Object Turns on use strict and use warnings
19
Declarative Attributes
has x => ( is => 'rw', isa => 'Num', required => 1); Creates an attribute called 'x' Makes it read/write Must be a number Is required
20
Housekeeping
Moose classes carry a lot of baggage We can (and should) turn some of it off no Moose;
Remove Moose exports from your namespace See also namespace::autoclean
__PACKAGE__->meta->make_immutable;
No more changes to class definition Performance improvements
Required Attributes
By default Moose attributes are optional Make them mandatory with required has x => (
... required => 1,); my $point1 = Point->new;
“Attribute (x) is required at constructor Point::new”
Attribute Defaults
Set a default for missing attributes has accuracy => ( default => 0.5,);
Or a subroutine reference has accuracy => ( default => sub { rand },);
Attribute Builder
Define a builder method instead of a default subroutine
has accuracy => ( builder => '_build_accuracy',);
sub _build_accuracy { return rand;}
Easier to subclass
24
Read/Write Attributes
Moose creates methods to access/alter attributes
$point1->x(-1);say $point1->x;
The 'is' property controls how they work 'rw' : read and write 'ro' : read only
25
Read/Write Attributes
But PBP says use get_* and set_*
has x => ( .... , reader => get_x, Writer => set_x,);
use MooseX::FollowPBP;
Rule of Thumb, pick a style and stick with it
26
Other Methods
Not all methods are constructors or accessors/mutators
Write other methods as usual First parameter is object reference
27
Other Methods
package Point;
...
sub distance
{
my $self = shift ;
my $newpoint = shift ;
return unless $newpoint->isa('Point') ;
return sqrt(
($self->x - $newpoint->x)**2
+
($self->y - $newpoint->y)**2
) ;
}
28
Using the Point
#!/usr/bin/perl
use Modern::Perl ;
use Point ;
my $point1 = Point->new(x=>-7,y=>-4) ;
my $point2 = Point->new(x=>17,y=>6) ;
say join ' ' , 'The Distance between point 1',
$point1->toString ,
'and point 2',
$point2->toString,
'is' , $point1->distance($point2) ;
# prints 'The Distance between point 1 (-7,-4) and point 2 (17,6) is 26'
Sub Classing
A subclass is a specialisation of a superclass More specific behaviour New attributes New methods Overriding superclass methods and attributes
30
package Point3D;use Moose;extends 'Point' ;
has z => ( is => 'rw', isa => 'Num', required => 1 );
override distance => sub { my $self = shift; my $newpoint = shift; return unless $newpoint->isa('Point3D') ; my $distance2d = super(); return sqrt( $distance2d**2 + ($self->z - $newpoint->z)**2 ) ;};
31
use Modern::Perl ;use Point3D ;
my $point1 = Point3D->new(x=>-7,y=>-4,z=>3);my $point2 = Point3D->new(x=>17,y=>6,z=>2.5);
say join ' ' , 'The Distance between point 1', $point1->toString , 'and point 2', $point2->toString, 'is' , $point1->distance($point2) ;# prints 'The Distance between point 1 (-7,-4,3) and point 2 (17,6,2.5) is 26.0048072478917'
32
Other Atrribute types
any Item Bool Maybe[`a] Undef Defined Value Str Num Int ClassName RoleName
Ref ScalarRef[`a] ArrayRef[`a] HashRef[`a] CodeRef RegexpRef GlobRef FileHandle Object
33
package Farm; use Moose;
has 'animals' => ( traits => ['Array'], is => 'ro', isa => 'ArrayRef[Animal]', default => sub { [] }, handles => { all_animals => 'elements', add_animal => 'push', find_animal => 'first', get_animal => 'get', count_animals => 'count', has_animals => 'count', has_no_animals => 'is_empty', sorted_animals => 'sort', }, );
no Moose; 1;
34
package Galaxy; use Moose;
has 'planets' => ( traits => ['Hash'], is => 'ro', isa => 'HashRef[Planets]', default => sub { {} }, handles => { set_planets => 'set', get_planets => 'get', has_no_planets => 'is_empty', num_planets => 'count', delete_planets => 'delete', }, );
no Moose; 1;
35
Further Information
Moose does a lot more We have only scratched the surface Good documentation
CPAN Moose::Manual::* Moose::Cookbook::*
No good book yet