-
Notifications
You must be signed in to change notification settings - Fork 0
/
notes_part_9_Moose.txt
133 lines (108 loc) · 3.82 KB
/
notes_part_9_Moose.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
------------------- Notes on Object Oriented Perl using Moose ------------------
A class usually belongs to a package which provides its name:
package Dog {
use Moose;
}
Objects (AKA instances of the "Dog" class) are created with the arrow operator:
my $fido = Dog->new;
my $scooby = Dog->new;
Methods: a method's first argument is its invocant ($self, by convention).
We want our Dog class to have a bark() method.
package Dog {
use Moose;
sub bark {
my $self = shift;
say "Woof";
}
}
Now we can create a Dog instance which barks three times:
my $barker = Dog->new;
$barker-> bark for 1 .. 3;
---------------------------------- Attributes ----------------------------------
To define attributes, declare them as part of the class:
package Dog {
use Moose;
# Dog objects have a name attribute, which is a read-only string.
has "name", is => "ro", isa => "Str";
Moose automatically creates an accessor named name(), which allows you to pass
a name into Dog's constructor.
for my $name (qw( Alan Bob Charlie)) {
my $dog = Dog->new( name => $name );
say "Created a dog for ", $dog->name;
}
--------------------------------- Encapsulation --------------------------------
Say we want to calculate a dog's age without giving internal details of the
object to external users of the object.
package Dog {
use Moose;
has 'name', is => 'ro', isa => 'Str';
has 'diet', is => 'rw';
has 'birth_year', is => 'ro', isa => 'Int';
sub age {
my $self = shift;
my $year = (localtime)[5] + 1900;
return $year - $self->birth_year;
}
}
Now, we want to customize the Dog constructor to allow passing in an age
parameter. We will also give a "default" value to users who construct
a dog object without providing a birth year.
package Cat {
use Moose;
has 'name', is => 'ro', isa => 'Str';
has 'diet', is => 'rw', isa => 'Str';
has 'birth_year',
is => 'ro',
isa => 'Int',
default => sub { (localtime)[5] + 1900 };
}
--------------------------------- Polymorphism ---------------------------------
You may treat any two instances with methods of the same name as equivalent; in
other words, Perl does not require any relationship declarations for
polymorphism to work.
A role is something a class does.
We can use roles to differentiate between living beings and inanimate objects,
for example:
package LivingBeing {
use Moose::Role;
requires qw( name age diet );
}
We then create a Dog class which must now declare that it plays the role of a
LivingBeing:
package Dog {
use Moose;
has 'name', is => 'ro', isa => 'Str';
has 'diet', is => 'rw', isa => 'Str';
has 'birth_year',
is => 'ro',
isa => 'Int',
default => sub { (localtime)[5] + 1900 };
with 'LivingBeing';
sub age { ... }
}
--------------------------------- Inheritance ----------------------------------
Use the "extends" keyword:
package LightSource {
use Moose;
has 'candle_power', is => 'ro',
isa => 'Int',
default => 1;
has 'enabled', is => 'ro',
isa => 'Bool',
default => 0,
writer => '_set_enabled';
sub light {
my $self = shift;
$self->_set_enabled( 1 );
}
sub extinguish {
my $self = shift;
$self->_set_enabled( 0 );
}
}
package SuperCandle {
use Moose;
extends 'LightSource';
has '+candle_power', default => 100;
}
________________________________________________________________________________