| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Moo; |
|
2
|
216
|
|
|
220
|
|
17558323
|
use strict; |
|
|
216
|
|
|
|
|
536
|
|
|
|
216
|
|
|
|
|
7004
|
|
|
3
|
216
|
|
|
220
|
|
1180
|
use warnings; |
|
|
216
|
|
|
|
|
445
|
|
|
|
216
|
|
|
|
|
6367
|
|
|
4
|
216
|
|
|
220
|
|
1133
|
no warnings 'once'; |
|
|
216
|
|
|
|
|
421
|
|
|
|
216
|
|
|
|
|
10411
|
|
|
5
|
|
|
|
|
|
|
|
|
6
|
216
|
|
|
|
|
18651
|
use Moo::_Utils qw( |
|
7
|
|
|
|
|
|
|
_check_tracked |
|
8
|
|
|
|
|
|
|
_getglob |
|
9
|
|
|
|
|
|
|
_getstash |
|
10
|
|
|
|
|
|
|
_install_coderef |
|
11
|
|
|
|
|
|
|
_install_modifier |
|
12
|
|
|
|
|
|
|
_install_tracked |
|
13
|
|
|
|
|
|
|
_linear_isa |
|
14
|
|
|
|
|
|
|
_load_module |
|
15
|
|
|
|
|
|
|
_set_loaded |
|
16
|
|
|
|
|
|
|
_unimport_coderefs |
|
17
|
216
|
|
|
220
|
|
63171
|
); |
|
|
216
|
|
|
|
|
553
|
|
|
18
|
216
|
|
|
220
|
|
1472
|
use Carp qw(croak); |
|
|
216
|
|
|
|
|
500
|
|
|
|
216
|
|
|
|
|
12619
|
|
|
19
|
|
|
|
|
|
|
BEGIN { |
|
20
|
216
|
|
|
220
|
|
71549
|
our @CARP_NOT = qw( |
|
21
|
|
|
|
|
|
|
Method::Generate::Constructor |
|
22
|
|
|
|
|
|
|
Method::Generate::Accessor |
|
23
|
|
|
|
|
|
|
Moo::sification |
|
24
|
|
|
|
|
|
|
Moo::_Utils |
|
25
|
|
|
|
|
|
|
Moo::Role |
|
26
|
|
|
|
|
|
|
); |
|
27
|
|
|
|
|
|
|
} |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
our $VERSION = '2.005004'; |
|
30
|
|
|
|
|
|
|
$VERSION =~ tr/_//d; |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
require Moo::sification; |
|
33
|
|
|
|
|
|
|
Moo::sification->import; |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
our %MAKERS; |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
sub import { |
|
38
|
780
|
|
|
784
|
|
1460883
|
my $target = caller; |
|
39
|
780
|
|
|
|
|
1552
|
my $class = shift; |
|
40
|
780
|
100
|
100
|
|
|
4172
|
if ($INC{'Role/Tiny.pm'} and Role::Tiny->is_role($target)) { |
|
41
|
6
|
|
|
|
|
1239
|
croak "Cannot import Moo into a role"; |
|
42
|
|
|
|
|
|
|
} |
|
43
|
|
|
|
|
|
|
|
|
44
|
774
|
|
|
|
|
6465
|
_set_loaded(caller); |
|
45
|
|
|
|
|
|
|
|
|
46
|
774
|
|
|
|
|
4853
|
strict->import; |
|
47
|
774
|
|
|
|
|
8785
|
warnings->import; |
|
48
|
|
|
|
|
|
|
|
|
49
|
774
|
|
|
|
|
2874
|
$class->_install_subs($target, @_); |
|
50
|
774
|
|
|
|
|
2658
|
$class->make_class($target); |
|
51
|
774
|
|
|
|
|
563939
|
return; |
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub make_class { |
|
55
|
774
|
|
|
778
|
0
|
1719
|
my ($me, $target) = @_; |
|
56
|
|
|
|
|
|
|
|
|
57
|
774
|
|
100
|
|
|
4228
|
my $makers = $MAKERS{$target} ||= {}; |
|
58
|
774
|
100
|
|
|
|
2607
|
return $target if $makers->{is_class}; |
|
59
|
|
|
|
|
|
|
|
|
60
|
770
|
|
|
|
|
2105
|
my $stash = _getstash($target); |
|
61
|
|
|
|
|
|
|
$makers->{non_methods} = { |
|
62
|
6468
|
|
|
|
|
17232
|
map +($_ => \&{"${target}::${_}"}), |
|
63
|
770
|
|
66
|
|
|
13708
|
grep exists &{"${target}::${_}"}, |
|
|
7414
|
|
|
|
|
14842
|
|
|
64
|
|
|
|
|
|
|
grep !/::\z/ && !/\A\(/, |
|
65
|
|
|
|
|
|
|
keys %$stash |
|
66
|
|
|
|
|
|
|
}; |
|
67
|
|
|
|
|
|
|
|
|
68
|
770
|
|
|
|
|
2467
|
$makers->{is_class} = 1; |
|
69
|
|
|
|
|
|
|
{ |
|
70
|
216
|
|
|
220
|
|
2039
|
no strict 'refs'; |
|
|
216
|
|
|
|
|
534
|
|
|
|
216
|
|
|
|
|
209326
|
|
|
|
770
|
|
|
|
|
1190
|
|
|
71
|
766
|
|
|
|
|
14890
|
@{"${target}::ISA"} = do { |
|
72
|
766
|
|
|
|
|
80654
|
require Moo::Object; ('Moo::Object'); |
|
|
766
|
|
|
|
|
1723
|
|
|
73
|
770
|
100
|
|
|
|
1318
|
} unless @{"${target}::ISA"}; |
|
|
770
|
|
|
|
|
5804
|
|
|
74
|
|
|
|
|
|
|
} |
|
75
|
770
|
100
|
100
|
|
|
4636
|
if ($INC{'Moo/HandleMoose.pm'} && !$Moo::sification::disabled) { |
|
76
|
68
|
|
|
|
|
435
|
Moo::HandleMoose::inject_fake_metaclass_for($target); |
|
77
|
|
|
|
|
|
|
} |
|
78
|
770
|
|
|
|
|
164574
|
return $target; |
|
79
|
|
|
|
|
|
|
} |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub is_class { |
|
82
|
0
|
|
|
4
|
0
|
0
|
my ($me, $class) = @_; |
|
83
|
0
|
|
0
|
|
|
0
|
return $MAKERS{$class} && $MAKERS{$class}{is_class}; |
|
84
|
|
|
|
|
|
|
} |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub _install_subs { |
|
87
|
774
|
|
|
778
|
|
1853
|
my ($me, $target) = @_; |
|
88
|
774
|
|
|
|
|
2258
|
my %install = $me->_gen_subs($target); |
|
89
|
|
|
|
|
|
|
_install_tracked $target => $_ => $install{$_} |
|
90
|
774
|
|
|
|
|
8101
|
for sort keys %install; |
|
91
|
774
|
|
|
|
|
2745
|
return; |
|
92
|
|
|
|
|
|
|
} |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub _gen_subs { |
|
95
|
774
|
|
|
778
|
|
1636
|
my ($me, $target) = @_; |
|
96
|
|
|
|
|
|
|
return ( |
|
97
|
|
|
|
|
|
|
extends => sub { |
|
98
|
152
|
|
|
156
|
|
153200
|
$me->_set_superclasses($target, @_); |
|
|
|
|
|
156
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
99
|
142
|
|
|
|
|
699
|
$me->_maybe_reset_handlemoose($target); |
|
100
|
142
|
|
|
|
|
3570
|
return; |
|
101
|
|
|
|
|
|
|
}, |
|
102
|
|
|
|
|
|
|
with => sub { |
|
103
|
112
|
|
|
112
|
|
26916
|
require Moo::Role; |
|
|
|
|
|
112
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
104
|
112
|
|
|
|
|
1142
|
Moo::Role->apply_roles_to_package($target, @_); |
|
105
|
100
|
|
|
|
|
5903
|
$me->_maybe_reset_handlemoose($target); |
|
106
|
|
|
|
|
|
|
}, |
|
107
|
|
|
|
|
|
|
has => sub { |
|
108
|
526
|
|
|
530
|
|
303423
|
my $name_proto = shift; |
|
|
|
|
|
530
|
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
109
|
526
|
100
|
|
|
|
2217
|
my @name_proto = ref $name_proto eq 'ARRAY' ? @$name_proto : $name_proto; |
|
110
|
526
|
100
|
|
|
|
2154
|
if (@_ % 2 != 0) { |
|
111
|
4
|
|
|
|
|
695
|
croak "Invalid options for " . join(', ', map "'$_'", @name_proto) |
|
112
|
|
|
|
|
|
|
. " attribute(s): even number of arguments expected, got " . scalar @_; |
|
113
|
|
|
|
|
|
|
} |
|
114
|
522
|
|
|
|
|
2279
|
my %spec = @_; |
|
115
|
522
|
|
|
|
|
1405
|
foreach my $name (@name_proto) { |
|
116
|
|
|
|
|
|
|
# Note that when multiple attributes specified, each attribute |
|
117
|
|
|
|
|
|
|
# needs a separate \%specs hashref |
|
118
|
524
|
100
|
|
|
|
1671
|
my $spec_ref = @name_proto > 1 ? +{%spec} : \%spec; |
|
119
|
524
|
|
|
|
|
2031
|
$me->_constructor_maker_for($target) |
|
120
|
|
|
|
|
|
|
->register_attribute_specs($name, $spec_ref); |
|
121
|
508
|
|
|
|
|
2345
|
$me->_accessor_maker_for($target) |
|
122
|
|
|
|
|
|
|
->generate_method($target, $name, $spec_ref); |
|
123
|
474
|
|
|
|
|
2374
|
$me->_maybe_reset_handlemoose($target); |
|
124
|
|
|
|
|
|
|
} |
|
125
|
472
|
|
|
|
|
9384
|
return; |
|
126
|
|
|
|
|
|
|
}, |
|
127
|
|
|
|
|
|
|
(map { |
|
128
|
774
|
|
|
|
|
9272
|
my $type = $_; |
|
|
2322
|
|
|
|
|
3947
|
|
|
129
|
|
|
|
|
|
|
( |
|
130
|
|
|
|
|
|
|
$type => sub { |
|
131
|
26
|
|
|
66
|
|
9037
|
_install_modifier($target, $type, @_); |
|
|
|
|
|
66
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
132
|
24
|
|
|
|
|
3570
|
return; |
|
133
|
|
|
|
|
|
|
}, |
|
134
|
|
|
|
|
|
|
) |
|
135
|
2322
|
|
|
|
|
11907
|
} qw(before after around)), |
|
136
|
|
|
|
|
|
|
); |
|
137
|
|
|
|
|
|
|
} |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub unimport { |
|
140
|
16
|
|
|
16
|
|
455
|
my $target = caller; |
|
141
|
16
|
|
|
|
|
47
|
_unimport_coderefs($target); |
|
142
|
|
|
|
|
|
|
} |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
sub _set_superclasses { |
|
145
|
152
|
|
|
152
|
|
361
|
my $class = shift; |
|
146
|
152
|
|
|
|
|
274
|
my $target = shift; |
|
147
|
152
|
|
|
|
|
540
|
foreach my $superclass (@_) { |
|
148
|
164
|
|
|
|
|
735
|
_load_module($superclass); |
|
149
|
160
|
100
|
100
|
|
|
964
|
if ($INC{'Role/Tiny.pm'} && Role::Tiny->is_role($superclass)) { |
|
150
|
4
|
|
|
|
|
992
|
croak "Can't extend role '$superclass'"; |
|
151
|
|
|
|
|
|
|
} |
|
152
|
|
|
|
|
|
|
} |
|
153
|
144
|
|
|
|
|
717
|
@{*{_getglob("${target}::ISA")}} = @_; |
|
|
144
|
|
|
|
|
251
|
|
|
|
144
|
|
|
|
|
605
|
|
|
154
|
144
|
100
|
|
|
|
2543
|
if (my $old = delete $Moo::MAKERS{$target}{constructor}) { |
|
|
|
100
|
|
|
|
|
|
|
155
|
6
|
|
|
|
|
30
|
$old->assert_constructor; |
|
156
|
4
|
|
|
|
|
14
|
delete _getstash($target)->{new}; |
|
157
|
|
|
|
|
|
|
Moo->_constructor_maker_for($target) |
|
158
|
4
|
|
|
|
|
19
|
->register_attribute_specs(%{$old->all_attribute_specs}); |
|
|
4
|
|
|
|
|
18
|
|
|
159
|
|
|
|
|
|
|
} |
|
160
|
|
|
|
|
|
|
elsif (!$target->isa('Moo::Object')) { |
|
161
|
44
|
|
|
|
|
197
|
Moo->_constructor_maker_for($target); |
|
162
|
|
|
|
|
|
|
} |
|
163
|
142
|
100
|
|
|
|
1322
|
$Moo::HandleMoose::MOUSE{$target} = [ |
|
164
|
|
|
|
|
|
|
grep defined, map Mouse::Util::find_meta($_), @_ |
|
165
|
|
|
|
|
|
|
] if Mouse::Util->can('find_meta'); |
|
166
|
|
|
|
|
|
|
} |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub _maybe_reset_handlemoose { |
|
169
|
716
|
|
|
716
|
|
1728
|
my ($class, $target) = @_; |
|
170
|
716
|
100
|
100
|
|
|
8144
|
if ($INC{'Moo/HandleMoose.pm'} && !$Moo::sification::disabled) { |
|
171
|
116
|
|
|
|
|
475
|
Moo::HandleMoose::maybe_reinject_fake_metaclass_for($target); |
|
172
|
|
|
|
|
|
|
} |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
sub _accessor_maker_for { |
|
176
|
1372
|
|
|
1372
|
|
3216
|
my ($class, $target) = @_; |
|
177
|
1372
|
100
|
|
|
|
3795
|
return unless $MAKERS{$target}; |
|
178
|
1360
|
|
66
|
|
|
6532
|
$MAKERS{$target}{accessor} ||= do { |
|
179
|
682
|
|
|
|
|
1062
|
my $maker_class = do { |
|
180
|
216
|
|
|
220
|
|
1889
|
no strict 'refs'; |
|
|
216
|
|
|
|
|
573
|
|
|
|
216
|
|
|
|
|
86123
|
|
|
181
|
682
|
100
|
|
|
|
1055
|
if (my $m = do { |
|
182
|
682
|
|
|
|
|
1040
|
my @isa = @{_linear_isa($target)}; |
|
|
682
|
|
|
|
|
4424
|
|
|
183
|
682
|
|
|
|
|
1351
|
shift @isa; |
|
184
|
682
|
100
|
|
|
|
1583
|
if (my ($parent_new) = grep +(defined &{$_.'::new'}), @isa) { |
|
|
844
|
|
|
|
|
4521
|
|
|
185
|
672
|
100
|
|
|
|
3211
|
$MAKERS{$parent_new} && $MAKERS{$parent_new}{accessor}; |
|
186
|
|
|
|
|
|
|
} |
|
187
|
|
|
|
|
|
|
else { |
|
188
|
10
|
|
|
|
|
40
|
undef; |
|
189
|
|
|
|
|
|
|
} |
|
190
|
|
|
|
|
|
|
}) { |
|
191
|
76
|
|
|
|
|
198
|
ref($m); |
|
192
|
|
|
|
|
|
|
} else { |
|
193
|
606
|
|
|
|
|
82869
|
require Method::Generate::Accessor; |
|
194
|
606
|
|
|
|
|
1962
|
'Method::Generate::Accessor' |
|
195
|
|
|
|
|
|
|
} |
|
196
|
|
|
|
|
|
|
}; |
|
197
|
682
|
|
|
|
|
6207
|
$maker_class->new; |
|
198
|
|
|
|
|
|
|
} |
|
199
|
|
|
|
|
|
|
} |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
sub _constructor_maker_for { |
|
202
|
984
|
|
|
984
|
|
85667
|
my ($class, $target) = @_; |
|
203
|
984
|
100
|
|
|
|
3350
|
return unless $MAKERS{$target}; |
|
204
|
962
|
|
66
|
|
|
4457
|
$MAKERS{$target}{constructor} ||= do { |
|
205
|
662
|
|
|
|
|
89903
|
require Method::Generate::Constructor; |
|
206
|
|
|
|
|
|
|
|
|
207
|
662
|
|
|
|
|
2951
|
my %construct_opts = ( |
|
208
|
|
|
|
|
|
|
package => $target, |
|
209
|
|
|
|
|
|
|
accessor_generator => $class->_accessor_maker_for($target), |
|
210
|
|
|
|
|
|
|
subconstructor_handler => ( |
|
211
|
|
|
|
|
|
|
' if ($Moo::MAKERS{$class}) {'."\n" |
|
212
|
|
|
|
|
|
|
.' if ($Moo::MAKERS{$class}{constructor}) {'."\n" |
|
213
|
|
|
|
|
|
|
.' package '.$target.';'."\n" |
|
214
|
|
|
|
|
|
|
.' return $invoker->SUPER::new(@_);'."\n" |
|
215
|
|
|
|
|
|
|
.' }'."\n" |
|
216
|
|
|
|
|
|
|
.' '.$class.'->_constructor_maker_for($class);'."\n" |
|
217
|
|
|
|
|
|
|
.' return $invoker->new(@_)'.";\n" |
|
218
|
|
|
|
|
|
|
.' } elsif ($INC{"Moose.pm"} and my $meta = Class::MOP::get_metaclass_by_name($class)) {'."\n" |
|
219
|
|
|
|
|
|
|
.' return $meta->new_object('."\n" |
|
220
|
|
|
|
|
|
|
.' $class->can("BUILDARGS") ? $class->BUILDARGS(@_)'."\n" |
|
221
|
|
|
|
|
|
|
.' : $class->Moo::Object::BUILDARGS(@_)'."\n" |
|
222
|
|
|
|
|
|
|
.' );'."\n" |
|
223
|
|
|
|
|
|
|
.' }'."\n" |
|
224
|
|
|
|
|
|
|
), |
|
225
|
|
|
|
|
|
|
); |
|
226
|
|
|
|
|
|
|
|
|
227
|
662
|
|
|
|
|
1520
|
my $con; |
|
228
|
662
|
|
|
|
|
1140
|
my @isa = @{_linear_isa($target)}; |
|
|
662
|
|
|
|
|
2866
|
|
|
229
|
662
|
|
|
|
|
1243
|
shift @isa; |
|
230
|
216
|
|
|
220
|
|
2484
|
no strict 'refs'; |
|
|
216
|
|
|
|
|
492
|
|
|
|
216
|
|
|
|
|
75111
|
|
|
231
|
662
|
100
|
|
|
|
1524
|
if (my ($parent_new) = grep +(defined &{$_.'::new'}), @isa) { |
|
|
826
|
|
|
|
|
5314
|
|
|
232
|
658
|
100
|
|
|
|
2647
|
if ($parent_new eq 'Moo::Object') { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
# no special constructor needed |
|
234
|
|
|
|
|
|
|
} |
|
235
|
|
|
|
|
|
|
elsif (my $makers = $MAKERS{$parent_new}) { |
|
236
|
80
|
|
|
|
|
177
|
$con = $makers->{constructor}; |
|
237
|
80
|
100
|
|
|
|
477
|
$construct_opts{construction_string} = $con->construction_string |
|
238
|
|
|
|
|
|
|
if $con; |
|
239
|
|
|
|
|
|
|
} |
|
240
|
|
|
|
|
|
|
elsif ($parent_new->can('BUILDALL')) { |
|
241
|
|
|
|
|
|
|
$construct_opts{construction_builder} = sub { |
|
242
|
14
|
100
|
|
14
|
|
97
|
my $inv = $target->can('BUILDARGS') ? '' : 'Moo::Object::'; |
|
243
|
14
|
|
|
|
|
146
|
'do {' |
|
244
|
|
|
|
|
|
|
.' my $args = $class->'.$inv.'BUILDARGS(@_);' |
|
245
|
|
|
|
|
|
|
.' $args->{__no_BUILD__} = 1;' |
|
246
|
|
|
|
|
|
|
.' $invoker->'.$target.'::SUPER::new($args);' |
|
247
|
|
|
|
|
|
|
.'}' |
|
248
|
14
|
|
|
|
|
118
|
}; |
|
249
|
|
|
|
|
|
|
} |
|
250
|
|
|
|
|
|
|
else { |
|
251
|
|
|
|
|
|
|
$construct_opts{construction_builder} = sub { |
|
252
|
24
|
100
|
|
24
|
|
341
|
'$invoker->'.$target.'::SUPER::new(' |
|
253
|
|
|
|
|
|
|
.($target->can('FOREIGNBUILDARGS') ? |
|
254
|
|
|
|
|
|
|
'$class->FOREIGNBUILDARGS(@_)' : '@_') |
|
255
|
|
|
|
|
|
|
.')' |
|
256
|
28
|
|
|
|
|
244
|
}; |
|
257
|
|
|
|
|
|
|
} |
|
258
|
|
|
|
|
|
|
} |
|
259
|
|
|
|
|
|
|
($con ? ref($con) : 'Method::Generate::Constructor') |
|
260
|
|
|
|
|
|
|
->new(%construct_opts) |
|
261
|
|
|
|
|
|
|
->install_delayed |
|
262
|
662
|
100
|
|
|
|
11408
|
->register_attribute_specs(%{$con?$con->all_attribute_specs:{}}) |
|
|
652
|
100
|
|
|
|
3557
|
|
|
263
|
|
|
|
|
|
|
} |
|
264
|
|
|
|
|
|
|
} |
|
265
|
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
sub _concrete_methods_of { |
|
267
|
82
|
|
|
82
|
|
666
|
my ($me, $class) = @_; |
|
268
|
82
|
|
|
|
|
253
|
my $makers = $MAKERS{$class}; |
|
269
|
|
|
|
|
|
|
|
|
270
|
82
|
|
100
|
|
|
406
|
my $non_methods = $makers->{non_methods} || {}; |
|
271
|
82
|
|
|
|
|
437
|
my $stash = _getstash($class); |
|
272
|
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
my $subs = { |
|
274
|
|
|
|
|
|
|
map {; |
|
275
|
216
|
|
|
220
|
|
1777
|
no strict 'refs'; |
|
|
216
|
|
|
|
|
552
|
|
|
|
216
|
|
|
|
|
54472
|
|
|
276
|
838
|
|
|
|
|
1025
|
${"${class}::${_}"} = ${"${class}::${_}"}; |
|
|
838
|
|
|
|
|
2972
|
|
|
|
838
|
|
|
|
|
1609
|
|
|
277
|
838
|
|
|
|
|
977
|
($_ => \&{"${class}::${_}"}); |
|
|
838
|
|
|
|
|
2338
|
|
|
278
|
|
|
|
|
|
|
} |
|
279
|
82
|
|
|
|
|
876
|
grep exists &{"${class}::${_}"}, |
|
|
1183
|
|
|
|
|
2475
|
|
|
280
|
|
|
|
|
|
|
grep !/::\z/, |
|
281
|
|
|
|
|
|
|
keys %$stash |
|
282
|
|
|
|
|
|
|
}; |
|
283
|
|
|
|
|
|
|
|
|
284
|
82
|
|
|
|
|
778
|
my %tracked = map +($_ => 1), _check_tracked($class, [ keys %$subs ]); |
|
285
|
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
return { |
|
287
|
380
|
|
|
|
|
1679
|
map +($_ => \&{"${class}::${_}"}), |
|
288
|
|
|
|
|
|
|
grep !($non_methods->{$_} && $non_methods->{$_} == $subs->{$_}), |
|
289
|
82
|
|
100
|
|
|
1082
|
grep !exists $tracked{$_}, |
|
290
|
|
|
|
|
|
|
keys %$subs |
|
291
|
|
|
|
|
|
|
}; |
|
292
|
|
|
|
|
|
|
} |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
1; |
|
295
|
|
|
|
|
|
|
__END__ |
|
296
|
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=pod |
|
298
|
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
=encoding utf-8 |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
=head1 NAME |
|
302
|
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
Moo - Minimalist Object Orientation (with Moose compatibility) |
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
306
|
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
package Cat::Food; |
|
308
|
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
use Moo; |
|
310
|
|
|
|
|
|
|
use strictures 2; |
|
311
|
|
|
|
|
|
|
use namespace::clean; |
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
sub feed_lion { |
|
314
|
|
|
|
|
|
|
my $self = shift; |
|
315
|
|
|
|
|
|
|
my $amount = shift || 1; |
|
316
|
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
$self->pounds( $self->pounds - $amount ); |
|
318
|
|
|
|
|
|
|
} |
|
319
|
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
has taste => ( |
|
321
|
|
|
|
|
|
|
is => 'ro', |
|
322
|
|
|
|
|
|
|
); |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
has brand => ( |
|
325
|
|
|
|
|
|
|
is => 'ro', |
|
326
|
|
|
|
|
|
|
isa => sub { |
|
327
|
|
|
|
|
|
|
die "Only SWEET-TREATZ supported!" unless $_[0] eq 'SWEET-TREATZ' |
|
328
|
|
|
|
|
|
|
}, |
|
329
|
|
|
|
|
|
|
); |
|
330
|
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
has pounds => ( |
|
332
|
|
|
|
|
|
|
is => 'rw', |
|
333
|
|
|
|
|
|
|
isa => sub { die "$_[0] is too much cat food!" unless $_[0] < 15 }, |
|
334
|
|
|
|
|
|
|
); |
|
335
|
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
1; |
|
337
|
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
And elsewhere: |
|
339
|
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
my $full = Cat::Food->new( |
|
341
|
|
|
|
|
|
|
taste => 'DELICIOUS.', |
|
342
|
|
|
|
|
|
|
brand => 'SWEET-TREATZ', |
|
343
|
|
|
|
|
|
|
pounds => 10, |
|
344
|
|
|
|
|
|
|
); |
|
345
|
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
$full->feed_lion; |
|
347
|
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
say $full->pounds; |
|
349
|
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
351
|
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
C<Moo> is an extremely light-weight Object Orientation system. It allows one to |
|
353
|
|
|
|
|
|
|
concisely define objects and roles with a convenient syntax that avoids the |
|
354
|
|
|
|
|
|
|
details of Perl's object system. C<Moo> contains a subset of L<Moose> and is |
|
355
|
|
|
|
|
|
|
optimised for rapid startup. |
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
C<Moo> avoids depending on any XS modules to allow for simple deployments. The |
|
358
|
|
|
|
|
|
|
name C<Moo> is based on the idea that it provides almost -- but not quite -- |
|
359
|
|
|
|
|
|
|
two thirds of L<Moose>. As such, the L<Moose::Manual> can serve as an effective |
|
360
|
|
|
|
|
|
|
guide to C<Moo> aside from the MOP and Types sections. |
|
361
|
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
Unlike L<Mouse> this module does not aim at full compatibility with |
|
363
|
|
|
|
|
|
|
L<Moose>'s surface syntax, preferring instead to provide full interoperability |
|
364
|
|
|
|
|
|
|
via the metaclass inflation capabilities described in L</MOO AND MOOSE>. |
|
365
|
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
For a full list of the minor differences between L<Moose> and L<Moo>'s surface |
|
367
|
|
|
|
|
|
|
syntax, see L</INCOMPATIBILITIES WITH MOOSE>. |
|
368
|
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=head1 WHY MOO EXISTS |
|
370
|
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
If you want a full object system with a rich Metaprotocol, L<Moose> is |
|
372
|
|
|
|
|
|
|
already wonderful. |
|
373
|
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
But if you don't want to use L<Moose>, you may not want "less metaprotocol" |
|
375
|
|
|
|
|
|
|
like L<Mouse> offers, but you probably want "no metaprotocol", which is what |
|
376
|
|
|
|
|
|
|
Moo provides. C<Moo> is ideal for some situations where deployment or startup |
|
377
|
|
|
|
|
|
|
time precludes using L<Moose> and L<Mouse>: |
|
378
|
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
=over 2 |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=item a command line or CGI script where fast startup is essential |
|
382
|
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=item code designed to be deployed as a single file via L<App::FatPacker> |
|
384
|
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
=item a CPAN module that may be used by others in the above situations |
|
386
|
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=back |
|
388
|
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
C<Moo> maintains transparent compatibility with L<Moose> so if you install and |
|
390
|
|
|
|
|
|
|
load L<Moose> you can use Moo classes and roles in L<Moose> code without |
|
391
|
|
|
|
|
|
|
modification. |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
Moo -- Minimal Object Orientation -- aims to make it smooth to upgrade to |
|
394
|
|
|
|
|
|
|
L<Moose> when you need more than the minimal features offered by Moo. |
|
395
|
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
=head1 MOO AND MOOSE |
|
397
|
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
If L<Moo> detects L<Moose> being loaded, it will automatically register |
|
399
|
|
|
|
|
|
|
metaclasses for your L<Moo> and L<Moo::Role> packages, so you should be able |
|
400
|
|
|
|
|
|
|
to use them in L<Moose> code without modification. |
|
401
|
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
L<Moo> will also create L<Moose type constraints|Moose::Manual::Types> for |
|
403
|
|
|
|
|
|
|
L<Moo> classes and roles, so that in Moose classes C<< isa => 'MyMooClass' >> |
|
404
|
|
|
|
|
|
|
and C<< isa => 'MyMooRole' >> work the same as for L<Moose> classes and roles. |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
Extending a L<Moose> class or consuming a L<Moose::Role> will also work. |
|
407
|
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
Extending a L<Mouse> class or consuming a L<Mouse::Role> will also work. But |
|
409
|
|
|
|
|
|
|
note that we don't provide L<Mouse> metaclasses or metaroles so the other way |
|
410
|
|
|
|
|
|
|
around doesn't work. This feature exists for L<Any::Moose> users porting to |
|
411
|
|
|
|
|
|
|
L<Moo>; enabling L<Mouse> users to use L<Moo> classes is not a priority for us. |
|
412
|
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
This means that there is no need for anything like L<Any::Moose> for Moo |
|
414
|
|
|
|
|
|
|
code - Moo and Moose code should simply interoperate without problem. To |
|
415
|
|
|
|
|
|
|
handle L<Mouse> code, you'll likely need an empty Moo role or class consuming |
|
416
|
|
|
|
|
|
|
or extending the L<Mouse> stuff since it doesn't register true L<Moose> |
|
417
|
|
|
|
|
|
|
metaclasses like L<Moo> does. |
|
418
|
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
If you need to disable the metaclass creation, add: |
|
420
|
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
no Moo::sification; |
|
422
|
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
to your code before Moose is loaded, but bear in mind that this switch is |
|
424
|
|
|
|
|
|
|
global and turns the mechanism off entirely so don't put this in library code. |
|
425
|
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=head1 MOO AND CLASS::XSACCESSOR |
|
427
|
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
If a new enough version of L<Class::XSAccessor> is available, it will be used |
|
429
|
|
|
|
|
|
|
to generate simple accessors, readers, and writers for better performance. |
|
430
|
|
|
|
|
|
|
Simple accessors are those without lazy defaults, type checks/coercions, or |
|
431
|
|
|
|
|
|
|
triggers. Simple readers are those without lazy defaults. Readers and writers |
|
432
|
|
|
|
|
|
|
generated by L<Class::XSAccessor> will behave slightly differently: they will |
|
433
|
|
|
|
|
|
|
reject attempts to call them with the incorrect number of parameters. |
|
434
|
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
=head1 MOO VERSUS ANY::MOOSE |
|
436
|
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
L<Any::Moose> will load L<Mouse> normally, and L<Moose> in a program using |
|
438
|
|
|
|
|
|
|
L<Moose> - which theoretically allows you to get the startup time of L<Mouse> |
|
439
|
|
|
|
|
|
|
without disadvantaging L<Moose> users. |
|
440
|
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
Sadly, this doesn't entirely work, since the selection is load order dependent |
|
442
|
|
|
|
|
|
|
- L<Moo>'s metaclass inflation system explained above in L</MOO AND MOOSE> is |
|
443
|
|
|
|
|
|
|
significantly more reliable. |
|
444
|
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
So if you want to write a CPAN module that loads fast or has only pure perl |
|
446
|
|
|
|
|
|
|
dependencies but is also fully usable by L<Moose> users, you should be using |
|
447
|
|
|
|
|
|
|
L<Moo>. |
|
448
|
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
For a full explanation, see the article |
|
450
|
|
|
|
|
|
|
L<https://shadow.cat/blog/matt-s-trout/moo-versus-any-moose> which explains |
|
451
|
|
|
|
|
|
|
the differing strategies in more detail and provides a direct example of |
|
452
|
|
|
|
|
|
|
where L<Moo> succeeds and L<Any::Moose> fails. |
|
453
|
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=head1 PUBLIC METHODS |
|
455
|
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
Moo provides several methods to any class using it. |
|
457
|
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
=head2 new |
|
459
|
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
Foo::Bar->new( attr1 => 3 ); |
|
461
|
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
or |
|
463
|
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
Foo::Bar->new({ attr1 => 3 }); |
|
465
|
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
The constructor for the class. By default it will accept attributes either as a |
|
467
|
|
|
|
|
|
|
hashref, or a list of key value pairs. This can be customized with the |
|
468
|
|
|
|
|
|
|
L</BUILDARGS> method. |
|
469
|
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
=head2 does |
|
471
|
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
if ($foo->does('Some::Role1')) { |
|
473
|
|
|
|
|
|
|
... |
|
474
|
|
|
|
|
|
|
} |
|
475
|
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
Returns true if the object composes in the passed role. |
|
477
|
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
=head2 DOES |
|
479
|
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
if ($foo->DOES('Some::Role1') || $foo->DOES('Some::Class1')) { |
|
481
|
|
|
|
|
|
|
... |
|
482
|
|
|
|
|
|
|
} |
|
483
|
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
Similar to L</does>, but will also return true for both composed roles and |
|
485
|
|
|
|
|
|
|
superclasses. |
|
486
|
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=head2 meta |
|
488
|
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
my $meta = Foo::Bar->meta; |
|
490
|
|
|
|
|
|
|
my @methods = $meta->get_method_list; |
|
491
|
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
Returns an object that will behave as if it is a |
|
493
|
|
|
|
|
|
|
L<Moose metaclass|Moose::Meta::Class> object for the class. If you call |
|
494
|
|
|
|
|
|
|
anything other than C<make_immutable> on it, the object will be transparently |
|
495
|
|
|
|
|
|
|
upgraded to a genuine L<Moose::Meta::Class> instance, loading Moose in the |
|
496
|
|
|
|
|
|
|
process if required. C<make_immutable> itself is a no-op, since we generate |
|
497
|
|
|
|
|
|
|
metaclasses that are already immutable, and users converting from Moose had |
|
498
|
|
|
|
|
|
|
an unfortunate tendency to accidentally load Moose by calling it. |
|
499
|
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
=head1 LIFECYCLE METHODS |
|
501
|
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
There are several methods that you can define in your class to control |
|
503
|
|
|
|
|
|
|
construction and destruction of objects. They should be used rather than trying |
|
504
|
|
|
|
|
|
|
to modify C<new> or C<DESTROY> yourself. |
|
505
|
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=head2 BUILDARGS |
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
around BUILDARGS => sub { |
|
509
|
|
|
|
|
|
|
my ( $orig, $class, @args ) = @_; |
|
510
|
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
return { attr1 => $args[0] } |
|
512
|
|
|
|
|
|
|
if @args == 1 && !ref $args[0]; |
|
513
|
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
return $class->$orig(@args); |
|
515
|
|
|
|
|
|
|
}; |
|
516
|
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
Foo::Bar->new( 3 ); |
|
518
|
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
This class method is used to transform the arguments to C<new> into a hash |
|
520
|
|
|
|
|
|
|
reference of attribute values. |
|
521
|
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
The default implementation accepts a hash or hash reference of named parameters. |
|
523
|
|
|
|
|
|
|
If it receives a single argument that isn't a hash reference it will throw an |
|
524
|
|
|
|
|
|
|
error. |
|
525
|
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
You can override this method in your class to handle other types of options |
|
527
|
|
|
|
|
|
|
passed to the constructor. |
|
528
|
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
This method should always return a hash reference of named options. |
|
530
|
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
=head2 FOREIGNBUILDARGS |
|
532
|
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
sub FOREIGNBUILDARGS { |
|
534
|
|
|
|
|
|
|
my ( $class, $options ) = @_; |
|
535
|
|
|
|
|
|
|
return $options->{foo}; |
|
536
|
|
|
|
|
|
|
} |
|
537
|
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
If you are inheriting from a non-Moo class, the arguments passed to the parent |
|
539
|
|
|
|
|
|
|
class constructor can be manipulated by defining a C<FOREIGNBUILDARGS> method. |
|
540
|
|
|
|
|
|
|
It will receive the same arguments as L</BUILDARGS>, and should return a list |
|
541
|
|
|
|
|
|
|
of arguments to pass to the parent class constructor. |
|
542
|
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
=head2 BUILD |
|
544
|
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
sub BUILD { |
|
546
|
|
|
|
|
|
|
my ($self, $args) = @_; |
|
547
|
|
|
|
|
|
|
die "foo and bar cannot be used at the same time" |
|
548
|
|
|
|
|
|
|
if exists $args->{foo} && exists $args->{bar}; |
|
549
|
|
|
|
|
|
|
} |
|
550
|
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
On object creation, any C<BUILD> methods in the class's inheritance hierarchy |
|
552
|
|
|
|
|
|
|
will be called on the object and given the results of L</BUILDARGS>. They each |
|
553
|
|
|
|
|
|
|
will be called in order from the parent classes down to the child, and thus |
|
554
|
|
|
|
|
|
|
should not themselves call the parent's method. Typically this is used for |
|
555
|
|
|
|
|
|
|
object validation or possibly logging. |
|
556
|
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
=head2 DEMOLISH |
|
558
|
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
sub DEMOLISH { |
|
560
|
|
|
|
|
|
|
my ($self, $in_global_destruction) = @_; |
|
561
|
|
|
|
|
|
|
... |
|
562
|
|
|
|
|
|
|
} |
|
563
|
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
When an object is destroyed, any C<DEMOLISH> methods in the inheritance |
|
565
|
|
|
|
|
|
|
hierarchy will be called on the object. They are given boolean to inform them |
|
566
|
|
|
|
|
|
|
if global destruction is in progress, and are called from the child class upwards |
|
567
|
|
|
|
|
|
|
to the parent. This is similar to L</BUILD> methods but in the opposite order. |
|
568
|
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
Note that this is implemented by a C<DESTROY> method, which is only created on |
|
570
|
|
|
|
|
|
|
on the first construction of an object of your class. This saves on overhead for |
|
571
|
|
|
|
|
|
|
classes that are never instantiated or those without C<DEMOLISH> methods. If you |
|
572
|
|
|
|
|
|
|
try to define your own C<DESTROY>, this will cause undefined results. |
|
573
|
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
=head1 IMPORTED SUBROUTINES |
|
575
|
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
=head2 extends |
|
577
|
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
extends 'Parent::Class'; |
|
579
|
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
Declares a base class. Multiple superclasses can be passed for multiple |
|
581
|
|
|
|
|
|
|
inheritance but please consider using L<roles|Moo::Role> instead. The class |
|
582
|
|
|
|
|
|
|
will be loaded but no errors will be triggered if the class can't be found and |
|
583
|
|
|
|
|
|
|
there are already subs in the class. |
|
584
|
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
Calling extends more than once will REPLACE your superclasses, not add to |
|
586
|
|
|
|
|
|
|
them like 'use base' would. |
|
587
|
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
=head2 with |
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
with 'Some::Role1'; |
|
591
|
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
or |
|
593
|
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
with 'Some::Role1', 'Some::Role2'; |
|
595
|
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
Composes one or more L<Moo::Role> (or L<Role::Tiny>) roles into the current |
|
597
|
|
|
|
|
|
|
class. An error will be raised if these roles cannot be composed because they |
|
598
|
|
|
|
|
|
|
have conflicting method definitions. The roles will be loaded using the same |
|
599
|
|
|
|
|
|
|
mechanism as C<extends> uses. |
|
600
|
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
=head2 has |
|
602
|
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
has attr => ( |
|
604
|
|
|
|
|
|
|
is => 'ro', |
|
605
|
|
|
|
|
|
|
); |
|
606
|
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
Declares an attribute for the class. |
|
608
|
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
package Foo; |
|
610
|
|
|
|
|
|
|
use Moo; |
|
611
|
|
|
|
|
|
|
has 'attr' => ( |
|
612
|
|
|
|
|
|
|
is => 'ro' |
|
613
|
|
|
|
|
|
|
); |
|
614
|
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
package Bar; |
|
616
|
|
|
|
|
|
|
use Moo; |
|
617
|
|
|
|
|
|
|
extends 'Foo'; |
|
618
|
|
|
|
|
|
|
has '+attr' => ( |
|
619
|
|
|
|
|
|
|
default => sub { "blah" }, |
|
620
|
|
|
|
|
|
|
); |
|
621
|
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
Using the C<+> notation, it's possible to override an attribute. |
|
623
|
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
has [qw(attr1 attr2 attr3)] => ( |
|
625
|
|
|
|
|
|
|
is => 'ro', |
|
626
|
|
|
|
|
|
|
); |
|
627
|
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
Using an arrayref with multiple attribute names, it's possible to declare |
|
629
|
|
|
|
|
|
|
multiple attributes with the same options. |
|
630
|
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
The options for C<has> are as follows: |
|
632
|
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
=over 2 |
|
634
|
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
=item C<is> |
|
636
|
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
B<required>, may be C<ro>, C<lazy>, C<rwp> or C<rw>. |
|
638
|
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
C<ro> stands for "read-only" and generates an accessor that dies if you attempt |
|
640
|
|
|
|
|
|
|
to write to it - i.e. a getter only - by defaulting C<reader> to the name of |
|
641
|
|
|
|
|
|
|
the attribute. |
|
642
|
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
C<lazy> generates a reader like C<ro>, but also sets C<lazy> to 1 and |
|
644
|
|
|
|
|
|
|
C<builder> to C<_build_${attribute_name}> to allow on-demand generated |
|
645
|
|
|
|
|
|
|
attributes. This feature was my attempt to fix my incompetence when |
|
646
|
|
|
|
|
|
|
originally designing C<lazy_build>, and is also implemented by |
|
647
|
|
|
|
|
|
|
L<MooseX::AttributeShortcuts>. There is, however, nothing to stop you |
|
648
|
|
|
|
|
|
|
using C<lazy> and C<builder> yourself with C<rwp> or C<rw> - it's just that |
|
649
|
|
|
|
|
|
|
this isn't generally a good idea so we don't provide a shortcut for it. |
|
650
|
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
C<rwp> stands for "read-write protected" and generates a reader like C<ro>, but |
|
652
|
|
|
|
|
|
|
also sets C<writer> to C<_set_${attribute_name}> for attributes that are |
|
653
|
|
|
|
|
|
|
designed to be written from inside of the class, but read-only from outside. |
|
654
|
|
|
|
|
|
|
This feature comes from L<MooseX::AttributeShortcuts>. |
|
655
|
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
C<rw> stands for "read-write" and generates a normal getter/setter by |
|
657
|
|
|
|
|
|
|
defaulting the C<accessor> to the name of the attribute specified. |
|
658
|
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
=item C<isa> |
|
660
|
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
Takes a coderef which is used to validate the attribute. Unlike L<Moose>, Moo |
|
662
|
|
|
|
|
|
|
does not include a basic type system, so instead of doing C<< isa => 'Num' >>, |
|
663
|
|
|
|
|
|
|
one should do |
|
664
|
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
use Scalar::Util qw(looks_like_number); |
|
666
|
|
|
|
|
|
|
... |
|
667
|
|
|
|
|
|
|
isa => sub { |
|
668
|
|
|
|
|
|
|
die "$_[0] is not a number!" unless looks_like_number $_[0] |
|
669
|
|
|
|
|
|
|
}, |
|
670
|
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
Note that the return value for C<isa> is discarded. Only if the sub dies does |
|
672
|
|
|
|
|
|
|
type validation fail. |
|
673
|
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
L<Sub::Quote aware|/SUB QUOTE AWARE> |
|
675
|
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
Since L<Moo> does B<not> run the C<isa> check before C<coerce> if a coercion |
|
677
|
|
|
|
|
|
|
subroutine has been supplied, C<isa> checks are not structural to your code |
|
678
|
|
|
|
|
|
|
and can, if desired, be omitted on non-debug builds (although if this results |
|
679
|
|
|
|
|
|
|
in an uncaught bug causing your program to break, the L<Moo> authors guarantee |
|
680
|
|
|
|
|
|
|
nothing except that you get to keep both halves). |
|
681
|
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
If you want L<Moose> compatible or L<MooseX::Types> style named types, look at |
|
683
|
|
|
|
|
|
|
L<Type::Tiny>. |
|
684
|
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
To cause your C<isa> entries to be automatically mapped to named |
|
686
|
|
|
|
|
|
|
L<Moose::Meta::TypeConstraint> objects (rather than the default behaviour |
|
687
|
|
|
|
|
|
|
of creating an anonymous type), set: |
|
688
|
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
$Moo::HandleMoose::TYPE_MAP{$isa_coderef} = sub { |
|
690
|
|
|
|
|
|
|
require MooseX::Types::Something; |
|
691
|
|
|
|
|
|
|
return MooseX::Types::Something::TypeName(); |
|
692
|
|
|
|
|
|
|
}; |
|
693
|
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
Note that this example is purely illustrative; anything that returns a |
|
695
|
|
|
|
|
|
|
L<Moose::Meta::TypeConstraint> object or something similar enough to it to |
|
696
|
|
|
|
|
|
|
make L<Moose> happy is fine. |
|
697
|
|
|
|
|
|
|
|
|
698
|
|
|
|
|
|
|
=item C<coerce> |
|
699
|
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
Takes a coderef which is meant to coerce the attribute. The basic idea is to |
|
701
|
|
|
|
|
|
|
do something like the following: |
|
702
|
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
coerce => sub { |
|
704
|
|
|
|
|
|
|
$_[0] % 2 ? $_[0] : $_[0] + 1 |
|
705
|
|
|
|
|
|
|
}, |
|
706
|
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
Note that L<Moo> will always execute your coercion: this is to permit |
|
708
|
|
|
|
|
|
|
C<isa> entries to be used purely for bug trapping, whereas coercions are |
|
709
|
|
|
|
|
|
|
always structural to your code. We do, however, apply any supplied C<isa> |
|
710
|
|
|
|
|
|
|
check after the coercion has run to ensure that it returned a valid value. |
|
711
|
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
L<Sub::Quote aware|/SUB QUOTE AWARE> |
|
713
|
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
If the C<isa> option is a blessed object providing a C<coerce> or |
|
715
|
|
|
|
|
|
|
C<coercion> method, then the C<coerce> option may be set to just C<1>. |
|
716
|
|
|
|
|
|
|
|
|
717
|
|
|
|
|
|
|
=item C<handles> |
|
718
|
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
Takes a string |
|
720
|
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
handles => 'RobotRole' |
|
722
|
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
Where C<RobotRole> is a L<role|Moo::Role> that defines an interface which |
|
724
|
|
|
|
|
|
|
becomes the list of methods to handle. |
|
725
|
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
Takes a list of methods |
|
727
|
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
handles => [ qw( one two ) ] |
|
729
|
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
Takes a hashref |
|
731
|
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
handles => { |
|
733
|
|
|
|
|
|
|
un => 'one', |
|
734
|
|
|
|
|
|
|
} |
|
735
|
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
=item C<trigger> |
|
737
|
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
Takes a coderef which will get called any time the attribute is set. This |
|
739
|
|
|
|
|
|
|
includes the constructor, but not default or built values. The coderef will be |
|
740
|
|
|
|
|
|
|
invoked against the object with the new value as an argument. |
|
741
|
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
If you set this to just C<1>, it generates a trigger which calls the |
|
743
|
|
|
|
|
|
|
C<_trigger_${attr_name}> method on C<$self>. This feature comes from |
|
744
|
|
|
|
|
|
|
L<MooseX::AttributeShortcuts>. |
|
745
|
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
Note that Moose also passes the old value, if any; this feature is not yet |
|
747
|
|
|
|
|
|
|
supported. |
|
748
|
|
|
|
|
|
|
|
|
749
|
|
|
|
|
|
|
L<Sub::Quote aware|/SUB QUOTE AWARE> |
|
750
|
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
=item C<default> |
|
752
|
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
Takes a coderef which will get called with $self as its only argument to |
|
754
|
|
|
|
|
|
|
populate an attribute if no value for that attribute was supplied to the |
|
755
|
|
|
|
|
|
|
constructor. Alternatively, if the attribute is lazy, C<default> executes when |
|
756
|
|
|
|
|
|
|
the attribute is first retrieved if no value has yet been provided. |
|
757
|
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
If a simple scalar is provided, it will be inlined as a string. Any non-code |
|
759
|
|
|
|
|
|
|
reference (hash, array) will result in an error - for that case instead use |
|
760
|
|
|
|
|
|
|
a code reference that returns the desired value. |
|
761
|
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
Note that if your default is fired during new() there is no guarantee that |
|
763
|
|
|
|
|
|
|
other attributes have been populated yet so you should not rely on their |
|
764
|
|
|
|
|
|
|
existence. |
|
765
|
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
L<Sub::Quote aware|/SUB QUOTE AWARE> |
|
767
|
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
=item C<predicate> |
|
769
|
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
Takes a method name which will return true if an attribute has a value. |
|
771
|
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
If you set this to just C<1>, the predicate is automatically named |
|
773
|
|
|
|
|
|
|
C<has_${attr_name}> if your attribute's name does not start with an |
|
774
|
|
|
|
|
|
|
underscore, or C<_has_${attr_name_without_the_underscore}> if it does. |
|
775
|
|
|
|
|
|
|
This feature comes from L<MooseX::AttributeShortcuts>. |
|
776
|
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
=item C<builder> |
|
778
|
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
Takes a method name which will be called to create the attribute - functions |
|
780
|
|
|
|
|
|
|
exactly like default except that instead of calling |
|
781
|
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
$default->($self); |
|
783
|
|
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
Moo will call |
|
785
|
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
$self->$builder; |
|
787
|
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
The following features come from L<MooseX::AttributeShortcuts>: |
|
789
|
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
If you set this to just C<1>, the builder is automatically named |
|
791
|
|
|
|
|
|
|
C<_build_${attr_name}>. |
|
792
|
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
If you set this to a coderef or code-convertible object, that variable will be |
|
794
|
|
|
|
|
|
|
installed under C<$class::_build_${attr_name}> and the builder set to the same |
|
795
|
|
|
|
|
|
|
name. |
|
796
|
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
=item C<clearer> |
|
798
|
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
Takes a method name which will clear the attribute. |
|
800
|
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
If you set this to just C<1>, the clearer is automatically named |
|
802
|
|
|
|
|
|
|
C<clear_${attr_name}> if your attribute's name does not start with an |
|
803
|
|
|
|
|
|
|
underscore, or C<_clear_${attr_name_without_the_underscore}> if it does. |
|
804
|
|
|
|
|
|
|
This feature comes from L<MooseX::AttributeShortcuts>. |
|
805
|
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
B<NOTE:> If the attribute is C<lazy>, it will be regenerated from C<default> or |
|
807
|
|
|
|
|
|
|
C<builder> the next time it is accessed. If it is not lazy, it will be C<undef>. |
|
808
|
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
=item C<lazy> |
|
810
|
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
B<Boolean>. Set this if you want values for the attribute to be grabbed |
|
812
|
|
|
|
|
|
|
lazily. This is usually a good idea if you have a L</builder> which requires |
|
813
|
|
|
|
|
|
|
another attribute to be set. |
|
814
|
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
=item C<required> |
|
816
|
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
B<Boolean>. Set this if the attribute must be passed on object instantiation. |
|
818
|
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
=item C<reader> |
|
820
|
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
The name of the method that returns the value of the attribute. If you like |
|
822
|
|
|
|
|
|
|
Java style methods, you might set this to C<get_foo> |
|
823
|
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
=item C<writer> |
|
825
|
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
The value of this attribute will be the name of the method to set the value of |
|
827
|
|
|
|
|
|
|
the attribute. If you like Java style methods, you might set this to |
|
828
|
|
|
|
|
|
|
C<set_foo>. |
|
829
|
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
=item C<weak_ref> |
|
831
|
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
B<Boolean>. Set this if you want the reference that the attribute contains to |
|
833
|
|
|
|
|
|
|
be weakened. Use this when circular references, which cause memory leaks, are |
|
834
|
|
|
|
|
|
|
possible. |
|
835
|
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
=item C<init_arg> |
|
837
|
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
Takes the name of the key to look for at instantiation time of the object. A |
|
839
|
|
|
|
|
|
|
common use of this is to make an underscored attribute have a non-underscored |
|
840
|
|
|
|
|
|
|
initialization name. C<undef> means that passing the value in on instantiation |
|
841
|
|
|
|
|
|
|
is ignored. |
|
842
|
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
=item C<moosify> |
|
844
|
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
Takes either a coderef or array of coderefs which is meant to transform the |
|
846
|
|
|
|
|
|
|
given attributes specifications if necessary when upgrading to a Moose role or |
|
847
|
|
|
|
|
|
|
class. You shouldn't need this by default, but is provided as a means of |
|
848
|
|
|
|
|
|
|
possible extensibility. |
|
849
|
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
=back |
|
851
|
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
=head2 before |
|
853
|
|
|
|
|
|
|
|
|
854
|
|
|
|
|
|
|
before foo => sub { ... }; |
|
855
|
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
See L<< Class::Method::Modifiers/before method(s) => sub { ... }; >> for full |
|
857
|
|
|
|
|
|
|
documentation. |
|
858
|
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
=head2 around |
|
860
|
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
around foo => sub { ... }; |
|
862
|
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
See L<< Class::Method::Modifiers/around method(s) => sub { ... }; >> for full |
|
864
|
|
|
|
|
|
|
documentation. |
|
865
|
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
=head2 after |
|
867
|
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
after foo => sub { ... }; |
|
869
|
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
See L<< Class::Method::Modifiers/after method(s) => sub { ... }; >> for full |
|
871
|
|
|
|
|
|
|
documentation. |
|
872
|
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
=head1 SUB QUOTE AWARE |
|
874
|
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
L<Sub::Quote/quote_sub> allows us to create coderefs that are "inlineable," |
|
876
|
|
|
|
|
|
|
giving us a handy, XS-free speed boost. Any option that is L<Sub::Quote> |
|
877
|
|
|
|
|
|
|
aware can take advantage of this. |
|
878
|
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
To do this, you can write |
|
880
|
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
use Sub::Quote; |
|
882
|
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
use Moo; |
|
884
|
|
|
|
|
|
|
use namespace::clean; |
|
885
|
|
|
|
|
|
|
|
|
886
|
|
|
|
|
|
|
has foo => ( |
|
887
|
|
|
|
|
|
|
is => 'ro', |
|
888
|
|
|
|
|
|
|
isa => quote_sub(q{ die "Not <3" unless $_[0] < 3 }) |
|
889
|
|
|
|
|
|
|
); |
|
890
|
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
which will be inlined as |
|
892
|
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
do { |
|
894
|
|
|
|
|
|
|
local @_ = ($_[0]->{foo}); |
|
895
|
|
|
|
|
|
|
die "Not <3" unless $_[0] < 3; |
|
896
|
|
|
|
|
|
|
} |
|
897
|
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
or to avoid localizing @_, |
|
899
|
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
has foo => ( |
|
901
|
|
|
|
|
|
|
is => 'ro', |
|
902
|
|
|
|
|
|
|
isa => quote_sub(q{ my ($val) = @_; die "Not <3" unless $val < 3 }) |
|
903
|
|
|
|
|
|
|
); |
|
904
|
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
which will be inlined as |
|
906
|
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
do { |
|
908
|
|
|
|
|
|
|
my ($val) = ($_[0]->{foo}); |
|
909
|
|
|
|
|
|
|
die "Not <3" unless $val < 3; |
|
910
|
|
|
|
|
|
|
} |
|
911
|
|
|
|
|
|
|
|
|
912
|
|
|
|
|
|
|
See L<Sub::Quote> for more information, including how to pass lexical |
|
913
|
|
|
|
|
|
|
captures that will also be compiled into the subroutine. |
|
914
|
|
|
|
|
|
|
|
|
915
|
|
|
|
|
|
|
=head1 CLEANING UP IMPORTS |
|
916
|
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
L<Moo> will not clean up imported subroutines for you; you will have |
|
918
|
|
|
|
|
|
|
to do that manually. The recommended way to do this is to declare your |
|
919
|
|
|
|
|
|
|
imports first, then C<use Moo>, then C<use namespace::clean>. |
|
920
|
|
|
|
|
|
|
Anything imported before L<namespace::clean> will be scrubbed. |
|
921
|
|
|
|
|
|
|
Anything imported or declared after will be still be available. |
|
922
|
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
package Record; |
|
924
|
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
use Digest::MD5 qw(md5_hex); |
|
926
|
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
use Moo; |
|
928
|
|
|
|
|
|
|
use namespace::clean; |
|
929
|
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
has name => (is => 'ro', required => 1); |
|
931
|
|
|
|
|
|
|
has id => (is => 'lazy'); |
|
932
|
|
|
|
|
|
|
sub _build_id { |
|
933
|
|
|
|
|
|
|
my ($self) = @_; |
|
934
|
|
|
|
|
|
|
return md5_hex($self->name); |
|
935
|
|
|
|
|
|
|
} |
|
936
|
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
1; |
|
938
|
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
For example if you were to import these subroutines after |
|
940
|
|
|
|
|
|
|
L<namespace::clean> like this |
|
941
|
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
use namespace::clean; |
|
943
|
|
|
|
|
|
|
|
|
944
|
|
|
|
|
|
|
use Digest::MD5 qw(md5_hex); |
|
945
|
|
|
|
|
|
|
use Moo; |
|
946
|
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
then any C<Record> C<$r> would have methods such as C<< $r->md5_hex() >>, |
|
948
|
|
|
|
|
|
|
C<< $r->has() >> and C<< $r->around() >> - almost certainly not what you |
|
949
|
|
|
|
|
|
|
intend! |
|
950
|
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
L<Moo::Role>s behave slightly differently. Since their methods are |
|
952
|
|
|
|
|
|
|
composed into the consuming class, they can do a little more for you |
|
953
|
|
|
|
|
|
|
automatically. As long as you declare your imports before calling |
|
954
|
|
|
|
|
|
|
C<use Moo::Role>, those imports and the ones L<Moo::Role> itself |
|
955
|
|
|
|
|
|
|
provides will not be composed into consuming classes so there's usually |
|
956
|
|
|
|
|
|
|
no need to use L<namespace::clean>. |
|
957
|
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
B<On L<namespace::autoclean>:> Older versions of L<namespace::autoclean> would |
|
959
|
|
|
|
|
|
|
inflate Moo classes to full L<Moose> classes, losing the benefits of Moo. If |
|
960
|
|
|
|
|
|
|
you want to use L<namespace::autoclean> with a Moo class, make sure you are |
|
961
|
|
|
|
|
|
|
using version 0.16 or newer. |
|
962
|
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
=head1 INCOMPATIBILITIES WITH MOOSE |
|
964
|
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
=head2 TYPES |
|
966
|
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
There is no built-in type system. C<isa> is verified with a coderef; if you |
|
968
|
|
|
|
|
|
|
need complex types, L<Type::Tiny> can provide types, type libraries, and |
|
969
|
|
|
|
|
|
|
will work seamlessly with both L<Moo> and L<Moose>. L<Type::Tiny> can be |
|
970
|
|
|
|
|
|
|
considered the successor to L<MooseX::Types> and provides a similar API, so |
|
971
|
|
|
|
|
|
|
that you can write |
|
972
|
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
use Types::Standard qw(Int); |
|
974
|
|
|
|
|
|
|
has days_to_live => (is => 'ro', isa => Int); |
|
975
|
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
=head2 API INCOMPATIBILITIES |
|
977
|
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
C<initializer> is not supported in core since the author considers it to be a |
|
979
|
|
|
|
|
|
|
bad idea and Moose best practices recommend avoiding it. Meanwhile C<trigger> or |
|
980
|
|
|
|
|
|
|
C<coerce> are more likely to be able to fulfill your needs. |
|
981
|
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
No support for C<super>, C<override>, C<inner>, or C<augment> - the author |
|
983
|
|
|
|
|
|
|
considers augment to be a bad idea, and override can be translated: |
|
984
|
|
|
|
|
|
|
|
|
985
|
|
|
|
|
|
|
override foo => sub { |
|
986
|
|
|
|
|
|
|
... |
|
987
|
|
|
|
|
|
|
super(); |
|
988
|
|
|
|
|
|
|
... |
|
989
|
|
|
|
|
|
|
}; |
|
990
|
|
|
|
|
|
|
|
|
991
|
|
|
|
|
|
|
around foo => sub { |
|
992
|
|
|
|
|
|
|
my ($orig, $self) = (shift, shift); |
|
993
|
|
|
|
|
|
|
... |
|
994
|
|
|
|
|
|
|
$self->$orig(@_); |
|
995
|
|
|
|
|
|
|
... |
|
996
|
|
|
|
|
|
|
}; |
|
997
|
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
The C<dump> method is not provided by default. The author suggests loading |
|
999
|
|
|
|
|
|
|
L<Devel::Dwarn> into C<main::> (via C<perl -MDevel::Dwarn ...> for example) and |
|
1000
|
|
|
|
|
|
|
using C<< $obj->$::Dwarn() >> instead. |
|
1001
|
|
|
|
|
|
|
|
|
1002
|
|
|
|
|
|
|
L</default> only supports coderefs and plain scalars, because passing a hash |
|
1003
|
|
|
|
|
|
|
or array reference as a default is almost always incorrect since the value is |
|
1004
|
|
|
|
|
|
|
then shared between all objects using that default. |
|
1005
|
|
|
|
|
|
|
|
|
1006
|
|
|
|
|
|
|
C<lazy_build> is not supported; you are instead encouraged to use the |
|
1007
|
|
|
|
|
|
|
C<< is => 'lazy' >> option supported by L<Moo> and |
|
1008
|
|
|
|
|
|
|
L<MooseX::AttributeShortcuts>. |
|
1009
|
|
|
|
|
|
|
|
|
1010
|
|
|
|
|
|
|
C<auto_deref> is not supported since the author considers it a bad idea and |
|
1011
|
|
|
|
|
|
|
it has been considered best practice to avoid it for some time. |
|
1012
|
|
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
C<documentation> will show up in a L<Moose> metaclass created from your class |
|
1014
|
|
|
|
|
|
|
but is otherwise ignored. Then again, L<Moose> ignores it as well, so this |
|
1015
|
|
|
|
|
|
|
is arguably not an incompatibility. |
|
1016
|
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
Since C<coerce> does not require C<isa> to be defined but L<Moose> does |
|
1018
|
|
|
|
|
|
|
require it, the metaclass inflation for coerce alone is a trifle insane |
|
1019
|
|
|
|
|
|
|
and if you attempt to subtype the result will almost certainly break. |
|
1020
|
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
Handling of warnings: when you C<use Moo> we enable strict and warnings, in a |
|
1022
|
|
|
|
|
|
|
similar way to Moose. The authors recommend the use of C<strictures>, which |
|
1023
|
|
|
|
|
|
|
enables FATAL warnings, and several extra pragmas when used in development: |
|
1024
|
|
|
|
|
|
|
L<indirect>, L<multidimensional>, and L<bareword::filehandles>. |
|
1025
|
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
Additionally, L<Moo> supports a set of attribute option shortcuts intended to |
|
1027
|
|
|
|
|
|
|
reduce common boilerplate. The set of shortcuts is the same as in the L<Moose> |
|
1028
|
|
|
|
|
|
|
module L<MooseX::AttributeShortcuts> as of its version 0.009+. So if you: |
|
1029
|
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
package MyClass; |
|
1031
|
|
|
|
|
|
|
use Moo; |
|
1032
|
|
|
|
|
|
|
use strictures 2; |
|
1033
|
|
|
|
|
|
|
|
|
1034
|
|
|
|
|
|
|
The nearest L<Moose> invocation would be: |
|
1035
|
|
|
|
|
|
|
|
|
1036
|
|
|
|
|
|
|
package MyClass; |
|
1037
|
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
use Moose; |
|
1039
|
|
|
|
|
|
|
use warnings FATAL => "all"; |
|
1040
|
|
|
|
|
|
|
use MooseX::AttributeShortcuts; |
|
1041
|
|
|
|
|
|
|
|
|
1042
|
|
|
|
|
|
|
or, if you're inheriting from a non-Moose class, |
|
1043
|
|
|
|
|
|
|
|
|
1044
|
|
|
|
|
|
|
package MyClass; |
|
1045
|
|
|
|
|
|
|
|
|
1046
|
|
|
|
|
|
|
use Moose; |
|
1047
|
|
|
|
|
|
|
use MooseX::NonMoose; |
|
1048
|
|
|
|
|
|
|
use warnings FATAL => "all"; |
|
1049
|
|
|
|
|
|
|
use MooseX::AttributeShortcuts; |
|
1050
|
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
=head2 META OBJECT |
|
1052
|
|
|
|
|
|
|
|
|
1053
|
|
|
|
|
|
|
There is no meta object. If you need this level of complexity you need |
|
1054
|
|
|
|
|
|
|
L<Moose> - Moo is small because it explicitly does not provide a metaprotocol. |
|
1055
|
|
|
|
|
|
|
However, if you load L<Moose>, then |
|
1056
|
|
|
|
|
|
|
|
|
1057
|
|
|
|
|
|
|
Class::MOP::class_of($moo_class_or_role) |
|
1058
|
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
will return an appropriate metaclass pre-populated by L<Moo>. |
|
1060
|
|
|
|
|
|
|
|
|
1061
|
|
|
|
|
|
|
=head2 IMMUTABILITY |
|
1062
|
|
|
|
|
|
|
|
|
1063
|
|
|
|
|
|
|
Finally, Moose requires you to call |
|
1064
|
|
|
|
|
|
|
|
|
1065
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
|
1066
|
|
|
|
|
|
|
|
|
1067
|
|
|
|
|
|
|
at the end of your class to get an inlined (i.e. not horribly slow) |
|
1068
|
|
|
|
|
|
|
constructor. Moo does it automatically the first time ->new is called |
|
1069
|
|
|
|
|
|
|
on your class. (C<make_immutable> is a no-op in Moo to ease migration.) |
|
1070
|
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
An extension L<MooX::late> exists to ease translating Moose packages |
|
1072
|
|
|
|
|
|
|
to Moo by providing a more Moose-like interface. |
|
1073
|
|
|
|
|
|
|
|
|
1074
|
|
|
|
|
|
|
=head1 COMPATIBILITY WITH OLDER PERL VERSIONS |
|
1075
|
|
|
|
|
|
|
|
|
1076
|
|
|
|
|
|
|
Moo is compatible with perl versions back to 5.6. When running on older |
|
1077
|
|
|
|
|
|
|
versions, additional prerequisites will be required. If you are packaging a |
|
1078
|
|
|
|
|
|
|
script with its dependencies, such as with L<App::FatPacker>, you will need to |
|
1079
|
|
|
|
|
|
|
be certain that the extra prerequisites are included. |
|
1080
|
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
=over 4 |
|
1082
|
|
|
|
|
|
|
|
|
1083
|
|
|
|
|
|
|
=item L<MRO::Compat> |
|
1084
|
|
|
|
|
|
|
|
|
1085
|
|
|
|
|
|
|
Required on perl versions prior to 5.10.0. |
|
1086
|
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
=item L<Devel::GlobalDestruction> |
|
1088
|
|
|
|
|
|
|
|
|
1089
|
|
|
|
|
|
|
Required on perl versions prior to 5.14.0. |
|
1090
|
|
|
|
|
|
|
|
|
1091
|
|
|
|
|
|
|
=back |
|
1092
|
|
|
|
|
|
|
|
|
1093
|
|
|
|
|
|
|
=head1 SUPPORT |
|
1094
|
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
IRC: #moose on irc.perl.org |
|
1096
|
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
=for :html |
|
1098
|
|
|
|
|
|
|
L<(click for instant chatroom login)|https://chat.mibbit.com/#moose@irc.perl.org> |
|
1099
|
|
|
|
|
|
|
|
|
1100
|
|
|
|
|
|
|
Bugtracker: L<https://rt.cpan.org/Public/Dist/Display.html?Name=Moo> |
|
1101
|
|
|
|
|
|
|
|
|
1102
|
|
|
|
|
|
|
Git repository: L<git://github.com/moose/Moo.git> |
|
1103
|
|
|
|
|
|
|
|
|
1104
|
|
|
|
|
|
|
Git browser: L<https://github.com/moose/Moo> |
|
1105
|
|
|
|
|
|
|
|
|
1106
|
|
|
|
|
|
|
=head1 AUTHOR |
|
1107
|
|
|
|
|
|
|
|
|
1108
|
|
|
|
|
|
|
mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk> |
|
1109
|
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
=head1 CONTRIBUTORS |
|
1111
|
|
|
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
dg - David Leadbeater (cpan:DGL) <dgl@dgl.cx> |
|
1113
|
|
|
|
|
|
|
|
|
1114
|
|
|
|
|
|
|
frew - Arthur Axel "fREW" Schmidt (cpan:FREW) <frioux@gmail.com> |
|
1115
|
|
|
|
|
|
|
|
|
1116
|
|
|
|
|
|
|
hobbs - Andrew Rodland (cpan:ARODLAND) <arodland@cpan.org> |
|
1117
|
|
|
|
|
|
|
|
|
1118
|
|
|
|
|
|
|
jnap - John Napiorkowski (cpan:JJNAPIORK) <jjn1056@yahoo.com> |
|
1119
|
|
|
|
|
|
|
|
|
1120
|
|
|
|
|
|
|
ribasushi - Peter Rabbitson (cpan:RIBASUSHI) <ribasushi@cpan.org> |
|
1121
|
|
|
|
|
|
|
|
|
1122
|
|
|
|
|
|
|
chip - Chip Salzenberg (cpan:CHIPS) <chip@pobox.com> |
|
1123
|
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
ajgb - Alex J. G. Burzyński (cpan:AJGB) <ajgb@cpan.org> |
|
1125
|
|
|
|
|
|
|
|
|
1126
|
|
|
|
|
|
|
doy - Jesse Luehrs (cpan:DOY) <doy at tozt dot net> |
|
1127
|
|
|
|
|
|
|
|
|
1128
|
|
|
|
|
|
|
perigrin - Chris Prather (cpan:PERIGRIN) <chris@prather.org> |
|
1129
|
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@googlemail.com> |
|
1131
|
|
|
|
|
|
|
|
|
1132
|
|
|
|
|
|
|
ilmari - Dagfinn Ilmari Mannsåker (cpan:ILMARI) <ilmari@ilmari.org> |
|
1133
|
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
tobyink - Toby Inkster (cpan:TOBYINK) <tobyink@cpan.org> |
|
1135
|
|
|
|
|
|
|
|
|
1136
|
|
|
|
|
|
|
haarg - Graham Knop (cpan:HAARG) <haarg@cpan.org> |
|
1137
|
|
|
|
|
|
|
|
|
1138
|
|
|
|
|
|
|
mattp - Matt Phillips (cpan:MATTP) <mattp@cpan.org> |
|
1139
|
|
|
|
|
|
|
|
|
1140
|
|
|
|
|
|
|
bluefeet - Aran Deltac (cpan:BLUEFEET) <bluefeet@gmail.com> |
|
1141
|
|
|
|
|
|
|
|
|
1142
|
|
|
|
|
|
|
bubaflub - Bob Kuo (cpan:BUBAFLUB) <bubaflub@cpan.org> |
|
1143
|
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
ether = Karen Etheridge (cpan:ETHER) <ether@cpan.org> |
|
1145
|
|
|
|
|
|
|
|
|
1146
|
|
|
|
|
|
|
=head1 COPYRIGHT |
|
1147
|
|
|
|
|
|
|
|
|
1148
|
|
|
|
|
|
|
Copyright (c) 2010-2015 the Moo L</AUTHOR> and L</CONTRIBUTORS> |
|
1149
|
|
|
|
|
|
|
as listed above. |
|
1150
|
|
|
|
|
|
|
|
|
1151
|
|
|
|
|
|
|
=head1 LICENSE |
|
1152
|
|
|
|
|
|
|
|
|
1153
|
|
|
|
|
|
|
This library is free software and may be distributed under the same terms |
|
1154
|
|
|
|
|
|
|
as perl itself. See L<https://dev.perl.org/licenses/>. |
|
1155
|
|
|
|
|
|
|
|
|
1156
|
|
|
|
|
|
|
=cut |