| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Class::MOP; |
|
2
|
|
|
|
|
|
|
our $VERSION = '2.2206'; |
|
3
|
|
|
|
|
|
|
|
|
4
|
450
|
|
|
450
|
|
4553734
|
use strict; |
|
|
450
|
|
|
|
|
1669
|
|
|
|
450
|
|
|
|
|
15201
|
|
|
5
|
450
|
|
|
450
|
|
2382
|
use warnings; |
|
|
450
|
|
|
|
|
1001
|
|
|
|
450
|
|
|
|
|
11337
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
450
|
|
|
450
|
|
8702
|
use 5.008003; |
|
|
450
|
|
|
|
|
2039
|
|
|
8
|
|
|
|
|
|
|
|
|
9
|
450
|
|
|
450
|
|
218945
|
use MRO::Compat; |
|
|
450
|
|
|
|
|
821271
|
|
|
|
450
|
|
|
|
|
15467
|
|
|
10
|
450
|
|
|
450
|
|
67208
|
use Class::Load 0.07 (); |
|
|
450
|
|
|
|
|
1864735
|
|
|
|
450
|
|
|
|
|
11953
|
|
|
11
|
450
|
|
|
450
|
|
2887
|
use Scalar::Util 'weaken', 'isweak', 'blessed'; |
|
|
450
|
|
|
|
|
1304
|
|
|
|
450
|
|
|
|
|
23832
|
|
|
12
|
450
|
|
|
450
|
|
4820
|
use Data::OptList; |
|
|
450
|
|
|
|
|
1925
|
|
|
|
450
|
|
|
|
|
3147
|
|
|
13
|
|
|
|
|
|
|
|
|
14
|
450
|
|
|
450
|
|
222855
|
use Class::MOP::Mixin::AttributeCore; |
|
|
450
|
|
|
|
|
1193
|
|
|
|
450
|
|
|
|
|
14039
|
|
|
15
|
450
|
|
|
450
|
|
205482
|
use Class::MOP::Mixin::HasAttributes; |
|
|
450
|
|
|
|
|
1212
|
|
|
|
450
|
|
|
|
|
13909
|
|
|
16
|
450
|
|
|
450
|
|
204496
|
use Class::MOP::Mixin::HasMethods; |
|
|
450
|
|
|
|
|
1543
|
|
|
|
450
|
|
|
|
|
14265
|
|
|
17
|
450
|
|
|
450
|
|
212238
|
use Class::MOP::Mixin::HasOverloads; |
|
|
450
|
|
|
|
|
1319
|
|
|
|
450
|
|
|
|
|
13015
|
|
|
18
|
450
|
|
|
450
|
|
313326
|
use Class::MOP::Class; |
|
|
450
|
|
|
|
|
1587
|
|
|
|
450
|
|
|
|
|
25268
|
|
|
19
|
450
|
|
|
450
|
|
263113
|
use Class::MOP::Attribute; |
|
|
450
|
|
|
|
|
1361
|
|
|
|
450
|
|
|
|
|
15151
|
|
|
20
|
450
|
|
|
450
|
|
5912
|
use Class::MOP::Method; |
|
|
450
|
|
|
|
|
1149
|
|
|
|
450
|
|
|
|
|
39317
|
|
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
BEGIN { |
|
23
|
|
|
|
|
|
|
*IS_RUNNING_ON_5_10 = ("$]" < 5.009_005) |
|
24
|
|
|
|
|
|
|
? sub () { 0 } |
|
25
|
450
|
50
|
|
450
|
|
4966
|
: sub () { 1 }; |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# this is either part of core or set up appropriately by MRO::Compat |
|
28
|
450
|
|
|
|
|
1116926
|
*check_package_cache_flag = \&mro::get_pkg_gen; |
|
29
|
|
|
|
|
|
|
} |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
XSLoader::load( |
|
32
|
|
|
|
|
|
|
'Moose', |
|
33
|
|
|
|
|
|
|
$VERSION, |
|
34
|
|
|
|
|
|
|
); |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
{ |
|
37
|
|
|
|
|
|
|
# Metaclasses are singletons, so we cache them here. |
|
38
|
|
|
|
|
|
|
# there is no need to worry about destruction though |
|
39
|
|
|
|
|
|
|
# because they should die only when the program dies. |
|
40
|
|
|
|
|
|
|
# After all, do package definitions even get reaped? |
|
41
|
|
|
|
|
|
|
# Anonymous classes manage their own destruction. |
|
42
|
|
|
|
|
|
|
my %METAS; |
|
43
|
|
|
|
|
|
|
|
|
44
|
1
|
|
|
1
|
1
|
309
|
sub get_all_metaclasses { %METAS } |
|
45
|
4
|
|
|
4
|
1
|
65
|
sub get_all_metaclass_instances { values %METAS } |
|
46
|
1
|
|
|
1
|
1
|
9
|
sub get_all_metaclass_names { keys %METAS } |
|
47
|
746452
|
|
|
746452
|
1
|
3373712
|
sub get_metaclass_by_name { $METAS{$_[0]} } |
|
48
|
31809
|
|
|
31809
|
1
|
110597
|
sub store_metaclass_by_name { $METAS{$_[0]} = $_[1] } |
|
49
|
117
|
|
|
117
|
1
|
517
|
sub weaken_metaclass { weaken($METAS{$_[0]}) } |
|
50
|
35187
|
|
|
35187
|
1
|
135698
|
sub metaclass_is_weak { isweak($METAS{$_[0]}) } |
|
51
|
22583
|
100
|
|
22583
|
1
|
157805
|
sub does_metaclass_exist { exists $METAS{$_[0]} && defined $METAS{$_[0]} } |
|
52
|
271
|
|
|
271
|
1
|
14817
|
sub remove_metaclass_by_name { delete $METAS{$_[0]}; return } |
|
|
271
|
|
|
|
|
709
|
|
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# This handles instances as well as class names |
|
55
|
|
|
|
|
|
|
sub class_of { |
|
56
|
38772
|
100
|
|
38772
|
1
|
108133
|
return unless defined $_[0]; |
|
57
|
38768
|
|
66
|
|
|
143247
|
my $class = blessed($_[0]) || $_[0]; |
|
58
|
38768
|
|
|
|
|
117157
|
return $METAS{$class}; |
|
59
|
|
|
|
|
|
|
} |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# NOTE: |
|
62
|
|
|
|
|
|
|
# We only cache metaclasses, meaning instances of |
|
63
|
|
|
|
|
|
|
# Class::MOP::Class. We do not cache instance of |
|
64
|
|
|
|
|
|
|
# Class::MOP::Package or Class::MOP::Module. Mostly |
|
65
|
|
|
|
|
|
|
# because I don't yet see a good reason to do so. |
|
66
|
|
|
|
|
|
|
} |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
sub load_class { |
|
69
|
1
|
|
|
1
|
0
|
171
|
Class::MOP::Deprecated::deprecated( |
|
70
|
|
|
|
|
|
|
message => 'Class::MOP::load_class is deprecated', |
|
71
|
|
|
|
|
|
|
feature => 'Class::Load wrapper functions', |
|
72
|
|
|
|
|
|
|
); |
|
73
|
1
|
|
|
|
|
309
|
require Class::Load; |
|
74
|
1
|
|
|
|
|
7
|
goto &Class::Load::load_class; |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub load_first_existing_class { |
|
78
|
1
|
|
|
1
|
0
|
752
|
Class::MOP::Deprecated::deprecated( |
|
79
|
|
|
|
|
|
|
message => 'Class::MOP::load_first_existing_class is deprecated', |
|
80
|
|
|
|
|
|
|
feature => 'Class::Load wrapper functions', |
|
81
|
|
|
|
|
|
|
); |
|
82
|
1
|
|
|
|
|
172
|
require Class::Load; |
|
83
|
1
|
|
|
|
|
6
|
goto &Class::Load::load_first_existing_class; |
|
84
|
|
|
|
|
|
|
} |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub is_class_loaded { |
|
87
|
1
|
|
|
1
|
0
|
450
|
Class::MOP::Deprecated::deprecated( |
|
88
|
|
|
|
|
|
|
message => 'Class::MOP::is_class_loaded is deprecated', |
|
89
|
|
|
|
|
|
|
feature => 'Class::Load wrapper functions', |
|
90
|
|
|
|
|
|
|
); |
|
91
|
1
|
|
|
|
|
181
|
require Class::Load; |
|
92
|
1
|
|
|
|
|
8
|
goto &Class::Load::is_class_loaded; |
|
93
|
|
|
|
|
|
|
} |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub _definition_context { |
|
96
|
54335
|
|
|
54335
|
|
86346
|
my %context; |
|
97
|
54335
|
|
|
|
|
419918
|
@context{qw(package file line)} = caller(0); |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
return ( |
|
100
|
54335
|
|
|
|
|
305540
|
definition_context => \%context, |
|
101
|
|
|
|
|
|
|
); |
|
102
|
|
|
|
|
|
|
} |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
## ---------------------------------------------------------------------------- |
|
105
|
|
|
|
|
|
|
## Setting up our environment ... |
|
106
|
|
|
|
|
|
|
## ---------------------------------------------------------------------------- |
|
107
|
|
|
|
|
|
|
## Class::MOP needs to have a few things in the global perl environment so |
|
108
|
|
|
|
|
|
|
## that it can operate effectively. Those things are done here. |
|
109
|
|
|
|
|
|
|
## ---------------------------------------------------------------------------- |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
# ... nothing yet actually ;) |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
## ---------------------------------------------------------------------------- |
|
114
|
|
|
|
|
|
|
## Bootstrapping |
|
115
|
|
|
|
|
|
|
## ---------------------------------------------------------------------------- |
|
116
|
|
|
|
|
|
|
## The code below here is to bootstrap our MOP with itself. This is also |
|
117
|
|
|
|
|
|
|
## sometimes called "tying the knot". By doing this, we make it much easier |
|
118
|
|
|
|
|
|
|
## to extend the MOP through subclassing and such since now you can use the |
|
119
|
|
|
|
|
|
|
## MOP itself to extend itself. |
|
120
|
|
|
|
|
|
|
## |
|
121
|
|
|
|
|
|
|
## Yes, I know, that's weird and insane, but it's a good thing, trust me :) |
|
122
|
|
|
|
|
|
|
## ---------------------------------------------------------------------------- |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# We need to add in the meta-attributes here so that |
|
125
|
|
|
|
|
|
|
# any subclass of Class::MOP::* will be able to |
|
126
|
|
|
|
|
|
|
# inherit them using _construct_instance |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
129
|
|
|
|
|
|
|
## Class::MOP::Mixin::HasMethods |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
Class::MOP::Mixin::HasMethods->meta->add_attribute( |
|
132
|
|
|
|
|
|
|
Class::MOP::Attribute->new('_methods' => ( |
|
133
|
|
|
|
|
|
|
reader => { |
|
134
|
|
|
|
|
|
|
# NOTE: |
|
135
|
|
|
|
|
|
|
# we just alias the original method |
|
136
|
|
|
|
|
|
|
# rather than re-produce it here |
|
137
|
|
|
|
|
|
|
'_method_map' => \&Class::MOP::Mixin::HasMethods::_method_map |
|
138
|
|
|
|
|
|
|
}, |
|
139
|
|
|
|
|
|
|
default => sub { {} }, |
|
140
|
|
|
|
|
|
|
_definition_context(), |
|
141
|
|
|
|
|
|
|
)) |
|
142
|
|
|
|
|
|
|
); |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
Class::MOP::Mixin::HasMethods->meta->add_attribute( |
|
145
|
|
|
|
|
|
|
Class::MOP::Attribute->new('method_metaclass' => ( |
|
146
|
|
|
|
|
|
|
reader => { |
|
147
|
|
|
|
|
|
|
# NOTE: |
|
148
|
|
|
|
|
|
|
# we just alias the original method |
|
149
|
|
|
|
|
|
|
# rather than re-produce it here |
|
150
|
|
|
|
|
|
|
'method_metaclass' => \&Class::MOP::Mixin::HasMethods::method_metaclass |
|
151
|
|
|
|
|
|
|
}, |
|
152
|
|
|
|
|
|
|
default => 'Class::MOP::Method', |
|
153
|
|
|
|
|
|
|
_definition_context(), |
|
154
|
|
|
|
|
|
|
)) |
|
155
|
|
|
|
|
|
|
); |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
Class::MOP::Mixin::HasMethods->meta->add_attribute( |
|
158
|
|
|
|
|
|
|
Class::MOP::Attribute->new('wrapped_method_metaclass' => ( |
|
159
|
|
|
|
|
|
|
reader => { |
|
160
|
|
|
|
|
|
|
# NOTE: |
|
161
|
|
|
|
|
|
|
# we just alias the original method |
|
162
|
|
|
|
|
|
|
# rather than re-produce it here |
|
163
|
|
|
|
|
|
|
'wrapped_method_metaclass' => \&Class::MOP::Mixin::HasMethods::wrapped_method_metaclass |
|
164
|
|
|
|
|
|
|
}, |
|
165
|
|
|
|
|
|
|
default => 'Class::MOP::Method::Wrapped', |
|
166
|
|
|
|
|
|
|
_definition_context(), |
|
167
|
|
|
|
|
|
|
)) |
|
168
|
|
|
|
|
|
|
); |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
171
|
|
|
|
|
|
|
## Class::MOP::Mixin::HasAttributes |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
Class::MOP::Mixin::HasAttributes->meta->add_attribute( |
|
174
|
|
|
|
|
|
|
Class::MOP::Attribute->new('attributes' => ( |
|
175
|
|
|
|
|
|
|
reader => { |
|
176
|
|
|
|
|
|
|
# NOTE: we need to do this in order |
|
177
|
|
|
|
|
|
|
# for the instance meta-object to |
|
178
|
|
|
|
|
|
|
# not fall into meta-circular death |
|
179
|
|
|
|
|
|
|
# |
|
180
|
|
|
|
|
|
|
# we just alias the original method |
|
181
|
|
|
|
|
|
|
# rather than re-produce it here |
|
182
|
|
|
|
|
|
|
'_attribute_map' => \&Class::MOP::Mixin::HasAttributes::_attribute_map |
|
183
|
|
|
|
|
|
|
}, |
|
184
|
|
|
|
|
|
|
default => sub { {} }, |
|
185
|
|
|
|
|
|
|
_definition_context(), |
|
186
|
|
|
|
|
|
|
)) |
|
187
|
|
|
|
|
|
|
); |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
Class::MOP::Mixin::HasAttributes->meta->add_attribute( |
|
190
|
|
|
|
|
|
|
Class::MOP::Attribute->new('attribute_metaclass' => ( |
|
191
|
|
|
|
|
|
|
reader => { |
|
192
|
|
|
|
|
|
|
# NOTE: |
|
193
|
|
|
|
|
|
|
# we just alias the original method |
|
194
|
|
|
|
|
|
|
# rather than re-produce it here |
|
195
|
|
|
|
|
|
|
'attribute_metaclass' => \&Class::MOP::Mixin::HasAttributes::attribute_metaclass |
|
196
|
|
|
|
|
|
|
}, |
|
197
|
|
|
|
|
|
|
default => 'Class::MOP::Attribute', |
|
198
|
|
|
|
|
|
|
_definition_context(), |
|
199
|
|
|
|
|
|
|
)) |
|
200
|
|
|
|
|
|
|
); |
|
201
|
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
203
|
|
|
|
|
|
|
## Class::MOP::Mixin::HasOverloads |
|
204
|
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
Class::MOP::Mixin::HasOverloads->meta->add_attribute( |
|
206
|
|
|
|
|
|
|
Class::MOP::Attribute->new('_overload_map' => ( |
|
207
|
|
|
|
|
|
|
reader => { |
|
208
|
|
|
|
|
|
|
'_overload_map' => \&Class::MOP::Mixin::HasOverloads::_overload_map |
|
209
|
|
|
|
|
|
|
}, |
|
210
|
|
|
|
|
|
|
clearer => '_clear_overload_map', |
|
211
|
|
|
|
|
|
|
default => sub { {} }, |
|
212
|
|
|
|
|
|
|
_definition_context(), |
|
213
|
|
|
|
|
|
|
)) |
|
214
|
|
|
|
|
|
|
); |
|
215
|
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
217
|
|
|
|
|
|
|
## Class::MOP::Package |
|
218
|
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
Class::MOP::Package->meta->add_attribute( |
|
220
|
|
|
|
|
|
|
Class::MOP::Attribute->new('package' => ( |
|
221
|
|
|
|
|
|
|
reader => { |
|
222
|
|
|
|
|
|
|
# NOTE: we need to do this in order |
|
223
|
|
|
|
|
|
|
# for the instance meta-object to |
|
224
|
|
|
|
|
|
|
# not fall into meta-circular death |
|
225
|
|
|
|
|
|
|
# |
|
226
|
|
|
|
|
|
|
# we just alias the original method |
|
227
|
|
|
|
|
|
|
# rather than re-produce it here |
|
228
|
|
|
|
|
|
|
'name' => \&Class::MOP::Package::name |
|
229
|
|
|
|
|
|
|
}, |
|
230
|
|
|
|
|
|
|
_definition_context(), |
|
231
|
|
|
|
|
|
|
)) |
|
232
|
|
|
|
|
|
|
); |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
Class::MOP::Package->meta->add_attribute( |
|
235
|
|
|
|
|
|
|
Class::MOP::Attribute->new('namespace' => ( |
|
236
|
|
|
|
|
|
|
reader => { |
|
237
|
|
|
|
|
|
|
# NOTE: |
|
238
|
|
|
|
|
|
|
# we just alias the original method |
|
239
|
|
|
|
|
|
|
# rather than re-produce it here |
|
240
|
|
|
|
|
|
|
'namespace' => \&Class::MOP::Package::namespace |
|
241
|
|
|
|
|
|
|
}, |
|
242
|
|
|
|
|
|
|
init_arg => undef, |
|
243
|
|
|
|
|
|
|
default => sub { \undef }, |
|
244
|
|
|
|
|
|
|
_definition_context(), |
|
245
|
|
|
|
|
|
|
)) |
|
246
|
|
|
|
|
|
|
); |
|
247
|
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
249
|
|
|
|
|
|
|
## Class::MOP::Module |
|
250
|
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# NOTE: |
|
252
|
|
|
|
|
|
|
# yeah this is kind of stretching things a bit, |
|
253
|
|
|
|
|
|
|
# but truthfully the version should be an attribute |
|
254
|
|
|
|
|
|
|
# of the Module, the weirdness comes from having to |
|
255
|
|
|
|
|
|
|
# stick to Perl 5 convention and store it in the |
|
256
|
|
|
|
|
|
|
# $VERSION package variable. Basically if you just |
|
257
|
|
|
|
|
|
|
# squint at it, it will look how you want it to look. |
|
258
|
|
|
|
|
|
|
# Either as a package variable, or as a attribute of |
|
259
|
|
|
|
|
|
|
# the metaclass, isn't abstraction great :) |
|
260
|
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
Class::MOP::Module->meta->add_attribute( |
|
262
|
|
|
|
|
|
|
Class::MOP::Attribute->new('version' => ( |
|
263
|
|
|
|
|
|
|
reader => { |
|
264
|
|
|
|
|
|
|
# NOTE: |
|
265
|
|
|
|
|
|
|
# we just alias the original method |
|
266
|
|
|
|
|
|
|
# rather than re-produce it here |
|
267
|
|
|
|
|
|
|
'version' => \&Class::MOP::Module::version |
|
268
|
|
|
|
|
|
|
}, |
|
269
|
|
|
|
|
|
|
init_arg => undef, |
|
270
|
|
|
|
|
|
|
default => sub { \undef }, |
|
271
|
|
|
|
|
|
|
_definition_context(), |
|
272
|
|
|
|
|
|
|
)) |
|
273
|
|
|
|
|
|
|
); |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
# NOTE: |
|
276
|
|
|
|
|
|
|
# By following the same conventions as version here, |
|
277
|
|
|
|
|
|
|
# we are opening up the possibility that people can |
|
278
|
|
|
|
|
|
|
# use the $AUTHORITY in non-Class::MOP modules as |
|
279
|
|
|
|
|
|
|
# well. |
|
280
|
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
Class::MOP::Module->meta->add_attribute( |
|
282
|
|
|
|
|
|
|
Class::MOP::Attribute->new('authority' => ( |
|
283
|
|
|
|
|
|
|
reader => { |
|
284
|
|
|
|
|
|
|
# NOTE: |
|
285
|
|
|
|
|
|
|
# we just alias the original method |
|
286
|
|
|
|
|
|
|
# rather than re-produce it here |
|
287
|
|
|
|
|
|
|
'authority' => \&Class::MOP::Module::authority |
|
288
|
|
|
|
|
|
|
}, |
|
289
|
|
|
|
|
|
|
init_arg => undef, |
|
290
|
|
|
|
|
|
|
default => sub { \undef }, |
|
291
|
|
|
|
|
|
|
_definition_context(), |
|
292
|
|
|
|
|
|
|
)) |
|
293
|
|
|
|
|
|
|
); |
|
294
|
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
296
|
|
|
|
|
|
|
## Class::MOP::Class |
|
297
|
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
Class::MOP::Class->meta->add_attribute( |
|
299
|
|
|
|
|
|
|
Class::MOP::Attribute->new('superclasses' => ( |
|
300
|
|
|
|
|
|
|
accessor => { |
|
301
|
|
|
|
|
|
|
# NOTE: |
|
302
|
|
|
|
|
|
|
# we just alias the original method |
|
303
|
|
|
|
|
|
|
# rather than re-produce it here |
|
304
|
|
|
|
|
|
|
'superclasses' => \&Class::MOP::Class::superclasses |
|
305
|
|
|
|
|
|
|
}, |
|
306
|
|
|
|
|
|
|
init_arg => undef, |
|
307
|
|
|
|
|
|
|
default => sub { \undef }, |
|
308
|
|
|
|
|
|
|
_definition_context(), |
|
309
|
|
|
|
|
|
|
)) |
|
310
|
|
|
|
|
|
|
); |
|
311
|
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
Class::MOP::Class->meta->add_attribute( |
|
313
|
|
|
|
|
|
|
Class::MOP::Attribute->new('instance_metaclass' => ( |
|
314
|
|
|
|
|
|
|
reader => { |
|
315
|
|
|
|
|
|
|
# NOTE: we need to do this in order |
|
316
|
|
|
|
|
|
|
# for the instance meta-object to |
|
317
|
|
|
|
|
|
|
# not fall into meta-circular death |
|
318
|
|
|
|
|
|
|
# |
|
319
|
|
|
|
|
|
|
# we just alias the original method |
|
320
|
|
|
|
|
|
|
# rather than re-produce it here |
|
321
|
|
|
|
|
|
|
'instance_metaclass' => \&Class::MOP::Class::instance_metaclass |
|
322
|
|
|
|
|
|
|
}, |
|
323
|
|
|
|
|
|
|
default => 'Class::MOP::Instance', |
|
324
|
|
|
|
|
|
|
_definition_context(), |
|
325
|
|
|
|
|
|
|
)) |
|
326
|
|
|
|
|
|
|
); |
|
327
|
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
Class::MOP::Class->meta->add_attribute( |
|
329
|
|
|
|
|
|
|
Class::MOP::Attribute->new('immutable_trait' => ( |
|
330
|
|
|
|
|
|
|
reader => { |
|
331
|
|
|
|
|
|
|
'immutable_trait' => \&Class::MOP::Class::immutable_trait |
|
332
|
|
|
|
|
|
|
}, |
|
333
|
|
|
|
|
|
|
default => "Class::MOP::Class::Immutable::Trait", |
|
334
|
|
|
|
|
|
|
_definition_context(), |
|
335
|
|
|
|
|
|
|
)) |
|
336
|
|
|
|
|
|
|
); |
|
337
|
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
Class::MOP::Class->meta->add_attribute( |
|
339
|
|
|
|
|
|
|
Class::MOP::Attribute->new('constructor_name' => ( |
|
340
|
|
|
|
|
|
|
reader => { |
|
341
|
|
|
|
|
|
|
'constructor_name' => \&Class::MOP::Class::constructor_name, |
|
342
|
|
|
|
|
|
|
}, |
|
343
|
|
|
|
|
|
|
default => "new", |
|
344
|
|
|
|
|
|
|
_definition_context(), |
|
345
|
|
|
|
|
|
|
)) |
|
346
|
|
|
|
|
|
|
); |
|
347
|
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
Class::MOP::Class->meta->add_attribute( |
|
349
|
|
|
|
|
|
|
Class::MOP::Attribute->new('constructor_class' => ( |
|
350
|
|
|
|
|
|
|
reader => { |
|
351
|
|
|
|
|
|
|
'constructor_class' => \&Class::MOP::Class::constructor_class, |
|
352
|
|
|
|
|
|
|
}, |
|
353
|
|
|
|
|
|
|
default => "Class::MOP::Method::Constructor", |
|
354
|
|
|
|
|
|
|
_definition_context(), |
|
355
|
|
|
|
|
|
|
)) |
|
356
|
|
|
|
|
|
|
); |
|
357
|
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
Class::MOP::Class->meta->add_attribute( |
|
360
|
|
|
|
|
|
|
Class::MOP::Attribute->new('destructor_class' => ( |
|
361
|
|
|
|
|
|
|
reader => { |
|
362
|
|
|
|
|
|
|
'destructor_class' => \&Class::MOP::Class::destructor_class, |
|
363
|
|
|
|
|
|
|
}, |
|
364
|
|
|
|
|
|
|
_definition_context(), |
|
365
|
|
|
|
|
|
|
)) |
|
366
|
|
|
|
|
|
|
); |
|
367
|
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
# NOTE: |
|
369
|
|
|
|
|
|
|
# we don't actually need to tie the knot with |
|
370
|
|
|
|
|
|
|
# Class::MOP::Class here, it is actually handled |
|
371
|
|
|
|
|
|
|
# within Class::MOP::Class itself in the |
|
372
|
|
|
|
|
|
|
# _construct_class_instance method. |
|
373
|
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
375
|
|
|
|
|
|
|
## Class::MOP::Mixin::AttributeCore |
|
376
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore->meta->add_attribute( |
|
377
|
|
|
|
|
|
|
Class::MOP::Attribute->new('name' => ( |
|
378
|
|
|
|
|
|
|
reader => { |
|
379
|
|
|
|
|
|
|
# NOTE: we need to do this in order |
|
380
|
|
|
|
|
|
|
# for the instance meta-object to |
|
381
|
|
|
|
|
|
|
# not fall into meta-circular death |
|
382
|
|
|
|
|
|
|
# |
|
383
|
|
|
|
|
|
|
# we just alias the original method |
|
384
|
|
|
|
|
|
|
# rather than re-produce it here |
|
385
|
|
|
|
|
|
|
'name' => \&Class::MOP::Mixin::AttributeCore::name |
|
386
|
|
|
|
|
|
|
}, |
|
387
|
|
|
|
|
|
|
_definition_context(), |
|
388
|
|
|
|
|
|
|
)) |
|
389
|
|
|
|
|
|
|
); |
|
390
|
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore->meta->add_attribute( |
|
392
|
|
|
|
|
|
|
Class::MOP::Attribute->new('accessor' => ( |
|
393
|
|
|
|
|
|
|
reader => { 'accessor' => \&Class::MOP::Mixin::AttributeCore::accessor }, |
|
394
|
|
|
|
|
|
|
predicate => { 'has_accessor' => \&Class::MOP::Mixin::AttributeCore::has_accessor }, |
|
395
|
|
|
|
|
|
|
_definition_context(), |
|
396
|
|
|
|
|
|
|
)) |
|
397
|
|
|
|
|
|
|
); |
|
398
|
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore->meta->add_attribute( |
|
400
|
|
|
|
|
|
|
Class::MOP::Attribute->new('reader' => ( |
|
401
|
|
|
|
|
|
|
reader => { 'reader' => \&Class::MOP::Mixin::AttributeCore::reader }, |
|
402
|
|
|
|
|
|
|
predicate => { 'has_reader' => \&Class::MOP::Mixin::AttributeCore::has_reader }, |
|
403
|
|
|
|
|
|
|
_definition_context(), |
|
404
|
|
|
|
|
|
|
)) |
|
405
|
|
|
|
|
|
|
); |
|
406
|
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore->meta->add_attribute( |
|
408
|
|
|
|
|
|
|
Class::MOP::Attribute->new('initializer' => ( |
|
409
|
|
|
|
|
|
|
reader => { 'initializer' => \&Class::MOP::Mixin::AttributeCore::initializer }, |
|
410
|
|
|
|
|
|
|
predicate => { 'has_initializer' => \&Class::MOP::Mixin::AttributeCore::has_initializer }, |
|
411
|
|
|
|
|
|
|
_definition_context(), |
|
412
|
|
|
|
|
|
|
)) |
|
413
|
|
|
|
|
|
|
); |
|
414
|
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore->meta->add_attribute( |
|
416
|
|
|
|
|
|
|
Class::MOP::Attribute->new('definition_context' => ( |
|
417
|
|
|
|
|
|
|
reader => { 'definition_context' => \&Class::MOP::Mixin::AttributeCore::definition_context }, |
|
418
|
|
|
|
|
|
|
_definition_context(), |
|
419
|
|
|
|
|
|
|
)) |
|
420
|
|
|
|
|
|
|
); |
|
421
|
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore->meta->add_attribute( |
|
423
|
|
|
|
|
|
|
Class::MOP::Attribute->new('writer' => ( |
|
424
|
|
|
|
|
|
|
reader => { 'writer' => \&Class::MOP::Mixin::AttributeCore::writer }, |
|
425
|
|
|
|
|
|
|
predicate => { 'has_writer' => \&Class::MOP::Mixin::AttributeCore::has_writer }, |
|
426
|
|
|
|
|
|
|
_definition_context(), |
|
427
|
|
|
|
|
|
|
)) |
|
428
|
|
|
|
|
|
|
); |
|
429
|
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore->meta->add_attribute( |
|
431
|
|
|
|
|
|
|
Class::MOP::Attribute->new('predicate' => ( |
|
432
|
|
|
|
|
|
|
reader => { 'predicate' => \&Class::MOP::Mixin::AttributeCore::predicate }, |
|
433
|
|
|
|
|
|
|
predicate => { 'has_predicate' => \&Class::MOP::Mixin::AttributeCore::has_predicate }, |
|
434
|
|
|
|
|
|
|
_definition_context(), |
|
435
|
|
|
|
|
|
|
)) |
|
436
|
|
|
|
|
|
|
); |
|
437
|
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore->meta->add_attribute( |
|
439
|
|
|
|
|
|
|
Class::MOP::Attribute->new('clearer' => ( |
|
440
|
|
|
|
|
|
|
reader => { 'clearer' => \&Class::MOP::Mixin::AttributeCore::clearer }, |
|
441
|
|
|
|
|
|
|
predicate => { 'has_clearer' => \&Class::MOP::Mixin::AttributeCore::has_clearer }, |
|
442
|
|
|
|
|
|
|
_definition_context(), |
|
443
|
|
|
|
|
|
|
)) |
|
444
|
|
|
|
|
|
|
); |
|
445
|
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore->meta->add_attribute( |
|
447
|
|
|
|
|
|
|
Class::MOP::Attribute->new('builder' => ( |
|
448
|
|
|
|
|
|
|
reader => { 'builder' => \&Class::MOP::Mixin::AttributeCore::builder }, |
|
449
|
|
|
|
|
|
|
predicate => { 'has_builder' => \&Class::MOP::Mixin::AttributeCore::has_builder }, |
|
450
|
|
|
|
|
|
|
_definition_context(), |
|
451
|
|
|
|
|
|
|
)) |
|
452
|
|
|
|
|
|
|
); |
|
453
|
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore->meta->add_attribute( |
|
455
|
|
|
|
|
|
|
Class::MOP::Attribute->new('init_arg' => ( |
|
456
|
|
|
|
|
|
|
reader => { 'init_arg' => \&Class::MOP::Mixin::AttributeCore::init_arg }, |
|
457
|
|
|
|
|
|
|
predicate => { 'has_init_arg' => \&Class::MOP::Mixin::AttributeCore::has_init_arg }, |
|
458
|
|
|
|
|
|
|
_definition_context(), |
|
459
|
|
|
|
|
|
|
)) |
|
460
|
|
|
|
|
|
|
); |
|
461
|
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore->meta->add_attribute( |
|
463
|
|
|
|
|
|
|
Class::MOP::Attribute->new('default' => ( |
|
464
|
|
|
|
|
|
|
# default has a custom 'reader' method ... |
|
465
|
|
|
|
|
|
|
predicate => { 'has_default' => \&Class::MOP::Mixin::AttributeCore::has_default }, |
|
466
|
|
|
|
|
|
|
_definition_context(), |
|
467
|
|
|
|
|
|
|
)) |
|
468
|
|
|
|
|
|
|
); |
|
469
|
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore->meta->add_attribute( |
|
471
|
|
|
|
|
|
|
Class::MOP::Attribute->new('insertion_order' => ( |
|
472
|
|
|
|
|
|
|
reader => { 'insertion_order' => \&Class::MOP::Mixin::AttributeCore::insertion_order }, |
|
473
|
|
|
|
|
|
|
writer => { '_set_insertion_order' => \&Class::MOP::Mixin::AttributeCore::_set_insertion_order }, |
|
474
|
|
|
|
|
|
|
predicate => { 'has_insertion_order' => \&Class::MOP::Mixin::AttributeCore::has_insertion_order }, |
|
475
|
|
|
|
|
|
|
_definition_context(), |
|
476
|
|
|
|
|
|
|
)) |
|
477
|
|
|
|
|
|
|
); |
|
478
|
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
480
|
|
|
|
|
|
|
## Class::MOP::Attribute |
|
481
|
|
|
|
|
|
|
Class::MOP::Attribute->meta->add_attribute( |
|
482
|
|
|
|
|
|
|
Class::MOP::Attribute->new('associated_class' => ( |
|
483
|
|
|
|
|
|
|
reader => { |
|
484
|
|
|
|
|
|
|
# NOTE: we need to do this in order |
|
485
|
|
|
|
|
|
|
# for the instance meta-object to |
|
486
|
|
|
|
|
|
|
# not fall into meta-circular death |
|
487
|
|
|
|
|
|
|
# |
|
488
|
|
|
|
|
|
|
# we just alias the original method |
|
489
|
|
|
|
|
|
|
# rather than re-produce it here |
|
490
|
|
|
|
|
|
|
'associated_class' => \&Class::MOP::Attribute::associated_class |
|
491
|
|
|
|
|
|
|
}, |
|
492
|
|
|
|
|
|
|
_definition_context(), |
|
493
|
|
|
|
|
|
|
)) |
|
494
|
|
|
|
|
|
|
); |
|
495
|
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
Class::MOP::Attribute->meta->add_attribute( |
|
497
|
|
|
|
|
|
|
Class::MOP::Attribute->new('associated_methods' => ( |
|
498
|
|
|
|
|
|
|
reader => { 'associated_methods' => \&Class::MOP::Attribute::associated_methods }, |
|
499
|
|
|
|
|
|
|
default => sub { [] }, |
|
500
|
|
|
|
|
|
|
_definition_context(), |
|
501
|
|
|
|
|
|
|
)) |
|
502
|
|
|
|
|
|
|
); |
|
503
|
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
Class::MOP::Attribute->meta->add_method('clone' => sub { |
|
505
|
6
|
|
|
6
|
|
6954
|
my $self = shift; |
|
506
|
6
|
|
|
|
|
32
|
$self->meta->clone_object($self, @_); |
|
507
|
|
|
|
|
|
|
}); |
|
508
|
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
510
|
|
|
|
|
|
|
## Class::MOP::Method |
|
511
|
|
|
|
|
|
|
Class::MOP::Method->meta->add_attribute( |
|
512
|
|
|
|
|
|
|
Class::MOP::Attribute->new('body' => ( |
|
513
|
|
|
|
|
|
|
reader => { 'body' => \&Class::MOP::Method::body }, |
|
514
|
|
|
|
|
|
|
_definition_context(), |
|
515
|
|
|
|
|
|
|
)) |
|
516
|
|
|
|
|
|
|
); |
|
517
|
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
Class::MOP::Method->meta->add_attribute( |
|
519
|
|
|
|
|
|
|
Class::MOP::Attribute->new('associated_metaclass' => ( |
|
520
|
|
|
|
|
|
|
reader => { 'associated_metaclass' => \&Class::MOP::Method::associated_metaclass }, |
|
521
|
|
|
|
|
|
|
_definition_context(), |
|
522
|
|
|
|
|
|
|
)) |
|
523
|
|
|
|
|
|
|
); |
|
524
|
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
Class::MOP::Method->meta->add_attribute( |
|
526
|
|
|
|
|
|
|
Class::MOP::Attribute->new('package_name' => ( |
|
527
|
|
|
|
|
|
|
reader => { 'package_name' => \&Class::MOP::Method::package_name }, |
|
528
|
|
|
|
|
|
|
_definition_context(), |
|
529
|
|
|
|
|
|
|
)) |
|
530
|
|
|
|
|
|
|
); |
|
531
|
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
Class::MOP::Method->meta->add_attribute( |
|
533
|
|
|
|
|
|
|
Class::MOP::Attribute->new('name' => ( |
|
534
|
|
|
|
|
|
|
reader => { 'name' => \&Class::MOP::Method::name }, |
|
535
|
|
|
|
|
|
|
_definition_context(), |
|
536
|
|
|
|
|
|
|
)) |
|
537
|
|
|
|
|
|
|
); |
|
538
|
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
Class::MOP::Method->meta->add_attribute( |
|
540
|
|
|
|
|
|
|
Class::MOP::Attribute->new('original_method' => ( |
|
541
|
|
|
|
|
|
|
reader => { 'original_method' => \&Class::MOP::Method::original_method }, |
|
542
|
|
|
|
|
|
|
writer => { '_set_original_method' => \&Class::MOP::Method::_set_original_method }, |
|
543
|
|
|
|
|
|
|
_definition_context(), |
|
544
|
|
|
|
|
|
|
)) |
|
545
|
|
|
|
|
|
|
); |
|
546
|
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
548
|
|
|
|
|
|
|
## Class::MOP::Method::Wrapped |
|
549
|
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
# NOTE: |
|
551
|
|
|
|
|
|
|
# the way this item is initialized, this |
|
552
|
|
|
|
|
|
|
# really does not follow the standard |
|
553
|
|
|
|
|
|
|
# practices of attributes, but we put |
|
554
|
|
|
|
|
|
|
# it here for completeness |
|
555
|
|
|
|
|
|
|
Class::MOP::Method::Wrapped->meta->add_attribute( |
|
556
|
|
|
|
|
|
|
Class::MOP::Attribute->new('modifier_table' => ( |
|
557
|
|
|
|
|
|
|
_definition_context(), |
|
558
|
|
|
|
|
|
|
)) |
|
559
|
|
|
|
|
|
|
); |
|
560
|
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
562
|
|
|
|
|
|
|
## Class::MOP::Method::Generated |
|
563
|
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
Class::MOP::Method::Generated->meta->add_attribute( |
|
565
|
|
|
|
|
|
|
Class::MOP::Attribute->new('is_inline' => ( |
|
566
|
|
|
|
|
|
|
reader => { 'is_inline' => \&Class::MOP::Method::Generated::is_inline }, |
|
567
|
|
|
|
|
|
|
default => 0, |
|
568
|
|
|
|
|
|
|
_definition_context(), |
|
569
|
|
|
|
|
|
|
)) |
|
570
|
|
|
|
|
|
|
); |
|
571
|
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
Class::MOP::Method::Generated->meta->add_attribute( |
|
573
|
|
|
|
|
|
|
Class::MOP::Attribute->new('definition_context' => ( |
|
574
|
|
|
|
|
|
|
reader => { 'definition_context' => \&Class::MOP::Method::Generated::definition_context }, |
|
575
|
|
|
|
|
|
|
_definition_context(), |
|
576
|
|
|
|
|
|
|
)) |
|
577
|
|
|
|
|
|
|
); |
|
578
|
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
581
|
|
|
|
|
|
|
## Class::MOP::Method::Inlined |
|
582
|
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
Class::MOP::Method::Inlined->meta->add_attribute( |
|
584
|
|
|
|
|
|
|
Class::MOP::Attribute->new('_expected_method_class' => ( |
|
585
|
|
|
|
|
|
|
reader => { '_expected_method_class' => \&Class::MOP::Method::Inlined::_expected_method_class }, |
|
586
|
|
|
|
|
|
|
_definition_context(), |
|
587
|
|
|
|
|
|
|
)) |
|
588
|
|
|
|
|
|
|
); |
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
591
|
|
|
|
|
|
|
## Class::MOP::Method::Accessor |
|
592
|
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
Class::MOP::Method::Accessor->meta->add_attribute( |
|
594
|
|
|
|
|
|
|
Class::MOP::Attribute->new('attribute' => ( |
|
595
|
|
|
|
|
|
|
reader => { |
|
596
|
|
|
|
|
|
|
'associated_attribute' => \&Class::MOP::Method::Accessor::associated_attribute |
|
597
|
|
|
|
|
|
|
}, |
|
598
|
|
|
|
|
|
|
_definition_context(), |
|
599
|
|
|
|
|
|
|
)) |
|
600
|
|
|
|
|
|
|
); |
|
601
|
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
Class::MOP::Method::Accessor->meta->add_attribute( |
|
603
|
|
|
|
|
|
|
Class::MOP::Attribute->new('accessor_type' => ( |
|
604
|
|
|
|
|
|
|
reader => { 'accessor_type' => \&Class::MOP::Method::Accessor::accessor_type }, |
|
605
|
|
|
|
|
|
|
_definition_context(), |
|
606
|
|
|
|
|
|
|
)) |
|
607
|
|
|
|
|
|
|
); |
|
608
|
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
610
|
|
|
|
|
|
|
## Class::MOP::Method::Constructor |
|
611
|
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
Class::MOP::Method::Constructor->meta->add_attribute( |
|
613
|
|
|
|
|
|
|
Class::MOP::Attribute->new('options' => ( |
|
614
|
|
|
|
|
|
|
reader => { |
|
615
|
|
|
|
|
|
|
'options' => \&Class::MOP::Method::Constructor::options |
|
616
|
|
|
|
|
|
|
}, |
|
617
|
|
|
|
|
|
|
default => sub { +{} }, |
|
618
|
|
|
|
|
|
|
_definition_context(), |
|
619
|
|
|
|
|
|
|
)) |
|
620
|
|
|
|
|
|
|
); |
|
621
|
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
Class::MOP::Method::Constructor->meta->add_attribute( |
|
623
|
|
|
|
|
|
|
Class::MOP::Attribute->new('associated_metaclass' => ( |
|
624
|
|
|
|
|
|
|
init_arg => "metaclass", # FIXME alias and rename |
|
625
|
|
|
|
|
|
|
reader => { |
|
626
|
|
|
|
|
|
|
'associated_metaclass' => \&Class::MOP::Method::Constructor::associated_metaclass |
|
627
|
|
|
|
|
|
|
}, |
|
628
|
|
|
|
|
|
|
_definition_context(), |
|
629
|
|
|
|
|
|
|
)) |
|
630
|
|
|
|
|
|
|
); |
|
631
|
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
633
|
|
|
|
|
|
|
## Class::MOP::Overload |
|
634
|
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
Class::MOP::Overload->meta->add_attribute( |
|
636
|
|
|
|
|
|
|
Class::MOP::Attribute->new( |
|
637
|
|
|
|
|
|
|
'operator' => ( |
|
638
|
|
|
|
|
|
|
reader => { 'operator' => \&Class::MOP::Overload::operator }, |
|
639
|
|
|
|
|
|
|
required => 1, |
|
640
|
|
|
|
|
|
|
_definition_context(), |
|
641
|
|
|
|
|
|
|
) |
|
642
|
|
|
|
|
|
|
) |
|
643
|
|
|
|
|
|
|
); |
|
644
|
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
for my $attr (qw( method_name coderef coderef_package coderef_name method )) { |
|
646
|
|
|
|
|
|
|
Class::MOP::Overload->meta->add_attribute( |
|
647
|
|
|
|
|
|
|
Class::MOP::Attribute->new( |
|
648
|
|
|
|
|
|
|
$attr => ( |
|
649
|
|
|
|
|
|
|
reader => { $attr => Class::MOP::Overload->can($attr) }, |
|
650
|
|
|
|
|
|
|
predicate => { |
|
651
|
|
|
|
|
|
|
'has_' |
|
652
|
|
|
|
|
|
|
. $attr => Class::MOP::Overload->can( 'has_' . $attr ) |
|
653
|
|
|
|
|
|
|
}, |
|
654
|
|
|
|
|
|
|
_definition_context(), |
|
655
|
|
|
|
|
|
|
) |
|
656
|
|
|
|
|
|
|
) |
|
657
|
|
|
|
|
|
|
); |
|
658
|
|
|
|
|
|
|
} |
|
659
|
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
Class::MOP::Overload->meta->add_attribute( |
|
661
|
|
|
|
|
|
|
Class::MOP::Attribute->new( |
|
662
|
|
|
|
|
|
|
'associated_metaclass' => ( |
|
663
|
|
|
|
|
|
|
reader => { |
|
664
|
|
|
|
|
|
|
'associated_metaclass' => |
|
665
|
|
|
|
|
|
|
\&Class::MOP::Overload::associated_metaclass |
|
666
|
|
|
|
|
|
|
}, |
|
667
|
|
|
|
|
|
|
_definition_context(), |
|
668
|
|
|
|
|
|
|
) |
|
669
|
|
|
|
|
|
|
) |
|
670
|
|
|
|
|
|
|
); |
|
671
|
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
673
|
|
|
|
|
|
|
## Class::MOP::Instance |
|
674
|
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
# NOTE: |
|
676
|
|
|
|
|
|
|
# these don't yet do much of anything, but are just |
|
677
|
|
|
|
|
|
|
# included for completeness |
|
678
|
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
Class::MOP::Instance->meta->add_attribute( |
|
680
|
|
|
|
|
|
|
Class::MOP::Attribute->new('associated_metaclass', |
|
681
|
|
|
|
|
|
|
reader => { associated_metaclass => \&Class::MOP::Instance::associated_metaclass }, |
|
682
|
|
|
|
|
|
|
_definition_context(), |
|
683
|
|
|
|
|
|
|
), |
|
684
|
|
|
|
|
|
|
); |
|
685
|
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
Class::MOP::Instance->meta->add_attribute( |
|
687
|
|
|
|
|
|
|
Class::MOP::Attribute->new('_class_name', |
|
688
|
|
|
|
|
|
|
init_arg => undef, |
|
689
|
|
|
|
|
|
|
reader => { _class_name => \&Class::MOP::Instance::_class_name }, |
|
690
|
|
|
|
|
|
|
#lazy => 1, # not yet supported by Class::MOP but out our version does it anyway |
|
691
|
|
|
|
|
|
|
#default => sub { $_[0]->associated_metaclass->name }, |
|
692
|
|
|
|
|
|
|
_definition_context(), |
|
693
|
|
|
|
|
|
|
), |
|
694
|
|
|
|
|
|
|
); |
|
695
|
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
Class::MOP::Instance->meta->add_attribute( |
|
697
|
|
|
|
|
|
|
Class::MOP::Attribute->new('attributes', |
|
698
|
|
|
|
|
|
|
reader => { attributes => \&Class::MOP::Instance::get_all_attributes }, |
|
699
|
|
|
|
|
|
|
_definition_context(), |
|
700
|
|
|
|
|
|
|
), |
|
701
|
|
|
|
|
|
|
); |
|
702
|
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
Class::MOP::Instance->meta->add_attribute( |
|
704
|
|
|
|
|
|
|
Class::MOP::Attribute->new('slots', |
|
705
|
|
|
|
|
|
|
reader => { slots => \&Class::MOP::Instance::slots }, |
|
706
|
|
|
|
|
|
|
_definition_context(), |
|
707
|
|
|
|
|
|
|
), |
|
708
|
|
|
|
|
|
|
); |
|
709
|
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
Class::MOP::Instance->meta->add_attribute( |
|
711
|
|
|
|
|
|
|
Class::MOP::Attribute->new('slot_hash', |
|
712
|
|
|
|
|
|
|
reader => { slot_hash => \&Class::MOP::Instance::slot_hash }, |
|
713
|
|
|
|
|
|
|
_definition_context(), |
|
714
|
|
|
|
|
|
|
), |
|
715
|
|
|
|
|
|
|
); |
|
716
|
|
|
|
|
|
|
|
|
717
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
718
|
|
|
|
|
|
|
## Class::MOP::Object |
|
719
|
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
# need to replace the meta method there with a real meta method object |
|
721
|
|
|
|
|
|
|
Class::MOP::Object->meta->_add_meta_method('meta'); |
|
722
|
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
724
|
|
|
|
|
|
|
## Class::MOP::Mixin |
|
725
|
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
# need to replace the meta method there with a real meta method object |
|
727
|
|
|
|
|
|
|
Class::MOP::Mixin->meta->_add_meta_method('meta'); |
|
728
|
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
require Class::MOP::Deprecated unless our $no_deprecated; |
|
730
|
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
# we need the meta instance of the meta instance to be created now, in order |
|
732
|
|
|
|
|
|
|
# for the constructor to be able to use it |
|
733
|
|
|
|
|
|
|
Class::MOP::Instance->meta->get_meta_instance; |
|
734
|
|
|
|
|
|
|
|
|
735
|
|
|
|
|
|
|
# pretend the add_method never happened. it hasn't yet affected anything |
|
736
|
|
|
|
|
|
|
undef Class::MOP::Instance->meta->{_package_cache_flag}; |
|
737
|
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
## -------------------------------------------------------- |
|
739
|
|
|
|
|
|
|
## Now close all the Class::MOP::* classes |
|
740
|
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
# NOTE: we don't need to inline the accessors this only lengthens the compile |
|
742
|
|
|
|
|
|
|
# time of the MOP, and gives us no actual benefits. |
|
743
|
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
$_->meta->make_immutable( |
|
745
|
|
|
|
|
|
|
inline_constructor => 0, |
|
746
|
|
|
|
|
|
|
constructor_name => "_new", |
|
747
|
|
|
|
|
|
|
inline_accessors => 0, |
|
748
|
|
|
|
|
|
|
) for qw/ |
|
749
|
|
|
|
|
|
|
Class::MOP::Package |
|
750
|
|
|
|
|
|
|
Class::MOP::Module |
|
751
|
|
|
|
|
|
|
Class::MOP::Class |
|
752
|
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
Class::MOP::Attribute |
|
754
|
|
|
|
|
|
|
Class::MOP::Method |
|
755
|
|
|
|
|
|
|
Class::MOP::Instance |
|
756
|
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
Class::MOP::Object |
|
758
|
|
|
|
|
|
|
|
|
759
|
|
|
|
|
|
|
Class::MOP::Method::Generated |
|
760
|
|
|
|
|
|
|
Class::MOP::Method::Inlined |
|
761
|
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
Class::MOP::Method::Accessor |
|
763
|
|
|
|
|
|
|
Class::MOP::Method::Constructor |
|
764
|
|
|
|
|
|
|
Class::MOP::Method::Wrapped |
|
765
|
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
Class::MOP::Method::Meta |
|
767
|
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
Class::MOP::Overload |
|
769
|
|
|
|
|
|
|
/; |
|
770
|
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
$_->meta->make_immutable( |
|
772
|
|
|
|
|
|
|
inline_constructor => 0, |
|
773
|
|
|
|
|
|
|
constructor_name => undef, |
|
774
|
|
|
|
|
|
|
inline_accessors => 0, |
|
775
|
|
|
|
|
|
|
) for qw/ |
|
776
|
|
|
|
|
|
|
Class::MOP::Mixin |
|
777
|
|
|
|
|
|
|
Class::MOP::Mixin::AttributeCore |
|
778
|
|
|
|
|
|
|
Class::MOP::Mixin::HasAttributes |
|
779
|
|
|
|
|
|
|
Class::MOP::Mixin::HasMethods |
|
780
|
|
|
|
|
|
|
Class::MOP::Mixin::HasOverloads |
|
781
|
|
|
|
|
|
|
/; |
|
782
|
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
1; |
|
784
|
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
# ABSTRACT: A Meta Object Protocol for Perl 5 |
|
786
|
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
__END__ |
|
788
|
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
=pod |
|
790
|
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
=encoding UTF-8 |
|
792
|
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
=head1 NAME |
|
794
|
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
Class::MOP - A Meta Object Protocol for Perl 5 |
|
796
|
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
=head1 VERSION |
|
798
|
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
version 2.2206 |
|
800
|
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
802
|
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
This module is a fully functioning meta object protocol for the |
|
804
|
|
|
|
|
|
|
Perl 5 object system. It makes no attempt to change the behavior or |
|
805
|
|
|
|
|
|
|
characteristics of the Perl 5 object system, only to create a |
|
806
|
|
|
|
|
|
|
protocol for its manipulation and introspection. |
|
807
|
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
That said, it does attempt to create the tools for building a rich set |
|
809
|
|
|
|
|
|
|
of extensions to the Perl 5 object system. Every attempt has been made |
|
810
|
|
|
|
|
|
|
to abide by the spirit of the Perl 5 object system that we all know |
|
811
|
|
|
|
|
|
|
and love. |
|
812
|
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
This documentation is sparse on conceptual details. We suggest looking |
|
814
|
|
|
|
|
|
|
at the items listed in the L<SEE ALSO> section for more |
|
815
|
|
|
|
|
|
|
information. In particular the book "The Art of the Meta Object |
|
816
|
|
|
|
|
|
|
Protocol" was very influential in the development of this system. |
|
817
|
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
=head2 What is a Meta Object Protocol? |
|
819
|
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
A meta object protocol is an API to an object system. |
|
821
|
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
To be more specific, it abstracts the components of an object system |
|
823
|
|
|
|
|
|
|
(classes, object, methods, object attributes, etc.). These |
|
824
|
|
|
|
|
|
|
abstractions can then be used to inspect and manipulate the object |
|
825
|
|
|
|
|
|
|
system which they describe. |
|
826
|
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
It can be said that there are two MOPs for any object system; the |
|
828
|
|
|
|
|
|
|
implicit MOP and the explicit MOP. The implicit MOP handles things |
|
829
|
|
|
|
|
|
|
like method dispatch or inheritance, which happen automatically as |
|
830
|
|
|
|
|
|
|
part of how the object system works. The explicit MOP typically |
|
831
|
|
|
|
|
|
|
handles the introspection/reflection features of the object system. |
|
832
|
|
|
|
|
|
|
|
|
833
|
|
|
|
|
|
|
All object systems have implicit MOPs. Without one, they would not |
|
834
|
|
|
|
|
|
|
work. Explicit MOPs are much less common, and depending on the |
|
835
|
|
|
|
|
|
|
language can vary from restrictive (Reflection in Java or C#) to wide |
|
836
|
|
|
|
|
|
|
open (CLOS is a perfect example). |
|
837
|
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
=head2 Yet Another Class Builder! Why? |
|
839
|
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
This is B<not> a class builder so much as a I<class builder |
|
841
|
|
|
|
|
|
|
B<builder>>. The intent is that an end user will not use this module |
|
842
|
|
|
|
|
|
|
directly, but instead this module is used by module authors to build |
|
843
|
|
|
|
|
|
|
extensions and features onto the Perl 5 object system. |
|
844
|
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
This system is used by L<Moose>, which supplies a powerful class |
|
846
|
|
|
|
|
|
|
builder system built entirely on top of C<Class::MOP>. |
|
847
|
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
=head2 Who is this module for? |
|
849
|
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
This module is for anyone who has ever created or wanted to create a |
|
851
|
|
|
|
|
|
|
module for the Class:: namespace. The tools which this module provides |
|
852
|
|
|
|
|
|
|
make doing complex Perl 5 wizardry simpler, by removing such barriers |
|
853
|
|
|
|
|
|
|
as the need to hack symbol tables, or understand the fine details of |
|
854
|
|
|
|
|
|
|
method dispatch. |
|
855
|
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
=head2 What changes do I have to make to use this module? |
|
857
|
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
This module was designed to be as unobtrusive as possible. Many of its |
|
859
|
|
|
|
|
|
|
features are accessible without B<any> change to your existing |
|
860
|
|
|
|
|
|
|
code. It is meant to be a complement to your existing code and not an |
|
861
|
|
|
|
|
|
|
intrusion on your code base. Unlike many other B<Class::> modules, |
|
862
|
|
|
|
|
|
|
this module B<does not> require you subclass it, or even that you |
|
863
|
|
|
|
|
|
|
C<use> it in within your module's package. |
|
864
|
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
The only features which require additions to your code are the |
|
866
|
|
|
|
|
|
|
attribute handling and instance construction features, and these are |
|
867
|
|
|
|
|
|
|
both completely optional features. The only reason for this is because |
|
868
|
|
|
|
|
|
|
Perl 5's object system does not actually have these features built |
|
869
|
|
|
|
|
|
|
in. More information about this feature can be found below. |
|
870
|
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
=head2 About Performance |
|
872
|
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
It is a common misconception that explicit MOPs are a performance hit. |
|
874
|
|
|
|
|
|
|
This is not a universal truth, it is a side-effect of some specific |
|
875
|
|
|
|
|
|
|
implementations. For instance, using Java reflection is slow because |
|
876
|
|
|
|
|
|
|
the JVM cannot take advantage of any compiler optimizations, and the |
|
877
|
|
|
|
|
|
|
JVM has to deal with much more runtime type information as well. |
|
878
|
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
Reflection in C# is marginally better as it was designed into the |
|
880
|
|
|
|
|
|
|
language and runtime (the CLR). In contrast, CLOS (the Common Lisp |
|
881
|
|
|
|
|
|
|
Object System) was built to support an explicit MOP, and so |
|
882
|
|
|
|
|
|
|
performance is tuned for it. |
|
883
|
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
This library in particular does its absolute best to avoid putting |
|
885
|
|
|
|
|
|
|
B<any> drain at all upon your code's performance. In fact, by itself |
|
886
|
|
|
|
|
|
|
it does nothing to affect your existing code. So you only pay for what |
|
887
|
|
|
|
|
|
|
you actually use. |
|
888
|
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
=head2 About Metaclass compatibility |
|
890
|
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
This module makes sure that all metaclasses created are both upwards |
|
892
|
|
|
|
|
|
|
and downwards compatible. The topic of metaclass compatibility is |
|
893
|
|
|
|
|
|
|
highly esoteric and is something only encountered when doing deep and |
|
894
|
|
|
|
|
|
|
involved metaclass hacking. There are two basic kinds of metaclass |
|
895
|
|
|
|
|
|
|
incompatibility; upwards and downwards. |
|
896
|
|
|
|
|
|
|
|
|
897
|
|
|
|
|
|
|
Upwards metaclass compatibility means that the metaclass of a |
|
898
|
|
|
|
|
|
|
given class is either the same as (or a subclass of) all of the |
|
899
|
|
|
|
|
|
|
metaclasses of the class's ancestors. |
|
900
|
|
|
|
|
|
|
|
|
901
|
|
|
|
|
|
|
Downward metaclass compatibility means that the metaclasses of a |
|
902
|
|
|
|
|
|
|
given class's ancestors are all the same as (or a subclass of) that |
|
903
|
|
|
|
|
|
|
class's metaclass. |
|
904
|
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
Here is a diagram showing a set of two classes (C<A> and C<B>) and |
|
906
|
|
|
|
|
|
|
two metaclasses (C<Meta::A> and C<Meta::B>) which have correct |
|
907
|
|
|
|
|
|
|
metaclass compatibility both upwards and downwards. |
|
908
|
|
|
|
|
|
|
|
|
909
|
|
|
|
|
|
|
+---------+ +---------+ |
|
910
|
|
|
|
|
|
|
| Meta::A |<----| Meta::B | <....... (instance of ) |
|
911
|
|
|
|
|
|
|
+---------+ +---------+ <------- (inherits from) |
|
912
|
|
|
|
|
|
|
^ ^ |
|
913
|
|
|
|
|
|
|
: : |
|
914
|
|
|
|
|
|
|
+---------+ +---------+ |
|
915
|
|
|
|
|
|
|
| A |<----| B | |
|
916
|
|
|
|
|
|
|
+---------+ +---------+ |
|
917
|
|
|
|
|
|
|
|
|
918
|
|
|
|
|
|
|
In actuality, I<all> of a class's metaclasses must be compatible, |
|
919
|
|
|
|
|
|
|
not just the class metaclass. That includes the instance, attribute, |
|
920
|
|
|
|
|
|
|
and method metaclasses, as well as the constructor and destructor |
|
921
|
|
|
|
|
|
|
classes. |
|
922
|
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
C<Class::MOP> will attempt to fix some simple types of |
|
924
|
|
|
|
|
|
|
incompatibilities. If all the metaclasses for the parent class are |
|
925
|
|
|
|
|
|
|
I<subclasses> of the child's metaclasses then we can simply replace |
|
926
|
|
|
|
|
|
|
the child's metaclasses with the parent's. In addition, if the child |
|
927
|
|
|
|
|
|
|
is missing a metaclass that the parent has, we can also just make the |
|
928
|
|
|
|
|
|
|
child use the parent's metaclass. |
|
929
|
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
As I said this is a highly esoteric topic and one you will only run |
|
931
|
|
|
|
|
|
|
into if you do a lot of subclassing of L<Class::MOP::Class>. If you |
|
932
|
|
|
|
|
|
|
are interested in why this is an issue see the paper I<Uniform and |
|
933
|
|
|
|
|
|
|
safe metaclass composition> linked to in the L<SEE ALSO> section of |
|
934
|
|
|
|
|
|
|
this document. |
|
935
|
|
|
|
|
|
|
|
|
936
|
|
|
|
|
|
|
=head2 Using custom metaclasses |
|
937
|
|
|
|
|
|
|
|
|
938
|
|
|
|
|
|
|
Always use the L<metaclass> pragma when using a custom metaclass, this |
|
939
|
|
|
|
|
|
|
will ensure the proper initialization order and not accidentally |
|
940
|
|
|
|
|
|
|
create an incorrect type of metaclass for you. This is a very rare |
|
941
|
|
|
|
|
|
|
problem, and one which can only occur if you are doing deep metaclass |
|
942
|
|
|
|
|
|
|
programming. So in other words, don't worry about it. |
|
943
|
|
|
|
|
|
|
|
|
944
|
|
|
|
|
|
|
Note that if you're using L<Moose> we encourage you to I<not> use the |
|
945
|
|
|
|
|
|
|
L<metaclass> pragma, and instead use L<Moose::Util::MetaRole> to apply |
|
946
|
|
|
|
|
|
|
roles to a class's metaclasses. This topic is covered at length in |
|
947
|
|
|
|
|
|
|
various L<Moose::Cookbook> recipes. |
|
948
|
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
=head1 PROTOCOLS |
|
950
|
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
The meta-object protocol is divided into 4 main sub-protocols: |
|
952
|
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
=head2 The Class protocol |
|
954
|
|
|
|
|
|
|
|
|
955
|
|
|
|
|
|
|
This provides a means of manipulating and introspecting a Perl 5 |
|
956
|
|
|
|
|
|
|
class. It handles symbol table hacking for you, and provides a rich |
|
957
|
|
|
|
|
|
|
set of methods that go beyond simple package introspection. |
|
958
|
|
|
|
|
|
|
|
|
959
|
|
|
|
|
|
|
See L<Class::MOP::Class> for more details. |
|
960
|
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
=head2 The Attribute protocol |
|
962
|
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
This provides a consistent representation for an attribute of a Perl 5 |
|
964
|
|
|
|
|
|
|
class. Since there are so many ways to create and handle attributes in |
|
965
|
|
|
|
|
|
|
Perl 5 OO, the Attribute protocol provide as much of a unified |
|
966
|
|
|
|
|
|
|
approach as possible. Of course, you are always free to extend this |
|
967
|
|
|
|
|
|
|
protocol by subclassing the appropriate classes. |
|
968
|
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
See L<Class::MOP::Attribute> for more details. |
|
970
|
|
|
|
|
|
|
|
|
971
|
|
|
|
|
|
|
=head2 The Method protocol |
|
972
|
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
This provides a means of manipulating and introspecting methods in the |
|
974
|
|
|
|
|
|
|
Perl 5 object system. As with attributes, there are many ways to |
|
975
|
|
|
|
|
|
|
approach this topic, so we try to keep it pretty basic, while still |
|
976
|
|
|
|
|
|
|
making it possible to extend the system in many ways. |
|
977
|
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
See L<Class::MOP::Method> for more details. |
|
979
|
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
=head2 The Instance protocol |
|
981
|
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
This provides a layer of abstraction for creating object instances. |
|
983
|
|
|
|
|
|
|
Since the other layers use this protocol, it is relatively easy to |
|
984
|
|
|
|
|
|
|
change the type of your instances from the default hash reference to |
|
985
|
|
|
|
|
|
|
some other type of reference. Several examples are provided in the |
|
986
|
|
|
|
|
|
|
F<examples/> directory included in this distribution. |
|
987
|
|
|
|
|
|
|
|
|
988
|
|
|
|
|
|
|
See L<Class::MOP::Instance> for more details. |
|
989
|
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
991
|
|
|
|
|
|
|
|
|
992
|
|
|
|
|
|
|
Note that this module does not export any constants or functions. |
|
993
|
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
=head2 Utility functions |
|
995
|
|
|
|
|
|
|
|
|
996
|
|
|
|
|
|
|
Note that these are all called as B<functions, not methods>. |
|
997
|
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
=head3 Class::MOP::get_code_info($code) |
|
999
|
|
|
|
|
|
|
|
|
1000
|
|
|
|
|
|
|
This function returns two values, the name of the package the C<$code> |
|
1001
|
|
|
|
|
|
|
is from and the name of the C<$code> itself. This is used by several |
|
1002
|
|
|
|
|
|
|
elements of the MOP to determine where a given C<$code> reference is |
|
1003
|
|
|
|
|
|
|
from. |
|
1004
|
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
=head3 Class::MOP::class_of($instance_or_class_name) |
|
1006
|
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
This will return the metaclass of the given instance or class name. If the |
|
1008
|
|
|
|
|
|
|
class lacks a metaclass, no metaclass will be initialized, and C<undef> will be |
|
1009
|
|
|
|
|
|
|
returned. |
|
1010
|
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
You should almost certainly be using |
|
1012
|
|
|
|
|
|
|
L<C<Moose::Util::find_meta>|Moose::Util/find_meta> instead. |
|
1013
|
|
|
|
|
|
|
|
|
1014
|
|
|
|
|
|
|
=head2 Metaclass cache functions |
|
1015
|
|
|
|
|
|
|
|
|
1016
|
|
|
|
|
|
|
C<Class::MOP> holds a cache of metaclasses. The following are functions |
|
1017
|
|
|
|
|
|
|
(B<not methods>) which can be used to access that cache. It is not |
|
1018
|
|
|
|
|
|
|
recommended that you mess with these. Bad things could happen, but if |
|
1019
|
|
|
|
|
|
|
you are brave and willing to risk it: go for it! |
|
1020
|
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
=head3 Class::MOP::get_all_metaclasses |
|
1022
|
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
This will return a hash of all the metaclass instances that have |
|
1024
|
|
|
|
|
|
|
been cached by L<Class::MOP::Class>, keyed by the package name. |
|
1025
|
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
=head3 Class::MOP::get_all_metaclass_instances |
|
1027
|
|
|
|
|
|
|
|
|
1028
|
|
|
|
|
|
|
This will return a list of all the metaclass instances that have |
|
1029
|
|
|
|
|
|
|
been cached by L<Class::MOP::Class>. |
|
1030
|
|
|
|
|
|
|
|
|
1031
|
|
|
|
|
|
|
=head3 Class::MOP::get_all_metaclass_names |
|
1032
|
|
|
|
|
|
|
|
|
1033
|
|
|
|
|
|
|
This will return a list of all the metaclass names that have |
|
1034
|
|
|
|
|
|
|
been cached by L<Class::MOP::Class>. |
|
1035
|
|
|
|
|
|
|
|
|
1036
|
|
|
|
|
|
|
=head3 Class::MOP::get_metaclass_by_name($name) |
|
1037
|
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
This will return a cached L<Class::MOP::Class> instance, or nothing |
|
1039
|
|
|
|
|
|
|
if no metaclass exists with that C<$name>. |
|
1040
|
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
=head3 Class::MOP::store_metaclass_by_name($name, $meta) |
|
1042
|
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
This will store a metaclass in the cache at the supplied C<$key>. |
|
1044
|
|
|
|
|
|
|
|
|
1045
|
|
|
|
|
|
|
=head3 Class::MOP::weaken_metaclass($name) |
|
1046
|
|
|
|
|
|
|
|
|
1047
|
|
|
|
|
|
|
In rare cases (e.g. anonymous metaclasses) it is desirable to |
|
1048
|
|
|
|
|
|
|
store a weakened reference in the metaclass cache. This |
|
1049
|
|
|
|
|
|
|
function will weaken the reference to the metaclass stored |
|
1050
|
|
|
|
|
|
|
in C<$name>. |
|
1051
|
|
|
|
|
|
|
|
|
1052
|
|
|
|
|
|
|
=head3 Class::MOP::metaclass_is_weak($name) |
|
1053
|
|
|
|
|
|
|
|
|
1054
|
|
|
|
|
|
|
Returns true if the metaclass for C<$name> has been weakened |
|
1055
|
|
|
|
|
|
|
(via C<weaken_metaclass>). |
|
1056
|
|
|
|
|
|
|
|
|
1057
|
|
|
|
|
|
|
=head3 Class::MOP::does_metaclass_exist($name) |
|
1058
|
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
This will return true of there exists a metaclass stored in the |
|
1060
|
|
|
|
|
|
|
C<$name> key, and return false otherwise. |
|
1061
|
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
=head3 Class::MOP::remove_metaclass_by_name($name) |
|
1063
|
|
|
|
|
|
|
|
|
1064
|
|
|
|
|
|
|
This will remove the metaclass stored in the C<$name> key. |
|
1065
|
|
|
|
|
|
|
|
|
1066
|
|
|
|
|
|
|
Some utility functions (such as C<Class::MOP::load_class>) that were |
|
1067
|
|
|
|
|
|
|
previously defined in C<Class::MOP> regarding loading of classes have been |
|
1068
|
|
|
|
|
|
|
extracted to L<Class::Load>. Please see L<Class::Load> for documentation. |
|
1069
|
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
1071
|
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
=head2 Books |
|
1073
|
|
|
|
|
|
|
|
|
1074
|
|
|
|
|
|
|
There are very few books out on Meta Object Protocols and Metaclasses |
|
1075
|
|
|
|
|
|
|
because it is such an esoteric topic. The following books are really |
|
1076
|
|
|
|
|
|
|
the only ones I have found. If you know of any more, B<I<please>> |
|
1077
|
|
|
|
|
|
|
email me and let me know, I would love to hear about them. |
|
1078
|
|
|
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
=over 4 |
|
1080
|
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
=item I<The Art of the Meta Object Protocol> |
|
1082
|
|
|
|
|
|
|
|
|
1083
|
|
|
|
|
|
|
=item I<Advances in Object-Oriented Metalevel Architecture and Reflection> |
|
1084
|
|
|
|
|
|
|
|
|
1085
|
|
|
|
|
|
|
=item I<Putting MetaClasses to Work> |
|
1086
|
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
=item I<Smalltalk: The Language> |
|
1088
|
|
|
|
|
|
|
|
|
1089
|
|
|
|
|
|
|
=back |
|
1090
|
|
|
|
|
|
|
|
|
1091
|
|
|
|
|
|
|
=head2 Papers |
|
1092
|
|
|
|
|
|
|
|
|
1093
|
|
|
|
|
|
|
=over 4 |
|
1094
|
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
=item "Uniform and safe metaclass composition" |
|
1096
|
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
An excellent paper by the people who brought us the original Traits paper. |
|
1098
|
|
|
|
|
|
|
This paper is on how Traits can be used to do safe metaclass composition, |
|
1099
|
|
|
|
|
|
|
and offers an excellent introduction section which delves into the topic of |
|
1100
|
|
|
|
|
|
|
metaclass compatibility. |
|
1101
|
|
|
|
|
|
|
|
|
1102
|
|
|
|
|
|
|
L<http://scg.unibe.ch/archive/papers/Duca05ySafeMetaclassTrait.pdf> |
|
1103
|
|
|
|
|
|
|
|
|
1104
|
|
|
|
|
|
|
=item "Safe Metaclass Programming" |
|
1105
|
|
|
|
|
|
|
|
|
1106
|
|
|
|
|
|
|
This paper seems to precede the above paper, and propose a mix-in based |
|
1107
|
|
|
|
|
|
|
approach as opposed to the Traits based approach. Both papers have similar |
|
1108
|
|
|
|
|
|
|
information on the metaclass compatibility problem space. |
|
1109
|
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
L<http://citeseer.ist.psu.edu/37617.html> |
|
1111
|
|
|
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
=back |
|
1113
|
|
|
|
|
|
|
|
|
1114
|
|
|
|
|
|
|
=head2 Prior Art |
|
1115
|
|
|
|
|
|
|
|
|
1116
|
|
|
|
|
|
|
=over 4 |
|
1117
|
|
|
|
|
|
|
|
|
1118
|
|
|
|
|
|
|
=item The Perl 6 MetaModel work in the Pugs project |
|
1119
|
|
|
|
|
|
|
|
|
1120
|
|
|
|
|
|
|
=over 4 |
|
1121
|
|
|
|
|
|
|
|
|
1122
|
|
|
|
|
|
|
=item L<http://github.com/perl6/p5-modules/tree/master/Perl6-ObjectSpace/> |
|
1123
|
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
=back |
|
1125
|
|
|
|
|
|
|
|
|
1126
|
|
|
|
|
|
|
=back |
|
1127
|
|
|
|
|
|
|
|
|
1128
|
|
|
|
|
|
|
=head2 Articles |
|
1129
|
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
=over 4 |
|
1131
|
|
|
|
|
|
|
|
|
1132
|
|
|
|
|
|
|
=item CPAN Module Review of Class::MOP |
|
1133
|
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
L<http://www.oreillynet.com/onlamp/blog/2006/06/cpan_module_review_classmop.html> |
|
1135
|
|
|
|
|
|
|
|
|
1136
|
|
|
|
|
|
|
=back |
|
1137
|
|
|
|
|
|
|
|
|
1138
|
|
|
|
|
|
|
=head1 SIMILAR MODULES |
|
1139
|
|
|
|
|
|
|
|
|
1140
|
|
|
|
|
|
|
As I have said above, this module is a class-builder-builder, so it is |
|
1141
|
|
|
|
|
|
|
not the same thing as modules like L<Class::Accessor> and |
|
1142
|
|
|
|
|
|
|
L<Class::MethodMaker>. That being said there are very few modules on CPAN |
|
1143
|
|
|
|
|
|
|
with similar goals to this module. The one I have found which is most |
|
1144
|
|
|
|
|
|
|
like this module is L<Class::Meta>, although its philosophy and the MOP it |
|
1145
|
|
|
|
|
|
|
creates are very different from this modules. |
|
1146
|
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
=head1 BUGS |
|
1148
|
|
|
|
|
|
|
|
|
1149
|
|
|
|
|
|
|
All complex software has bugs lurking in it, and this module is no |
|
1150
|
|
|
|
|
|
|
exception. |
|
1151
|
|
|
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
Please report any bugs to C<bug-class-mop@rt.cpan.org>, or through the |
|
1153
|
|
|
|
|
|
|
web interface at L<http://rt.cpan.org>. |
|
1154
|
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
You can also discuss feature requests or possible bugs on the Moose |
|
1156
|
|
|
|
|
|
|
mailing list (moose@perl.org) or on IRC at |
|
1157
|
|
|
|
|
|
|
L<irc://irc.perl.org/#moose>. |
|
1158
|
|
|
|
|
|
|
|
|
1159
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
|
1160
|
|
|
|
|
|
|
|
|
1161
|
|
|
|
|
|
|
=over 4 |
|
1162
|
|
|
|
|
|
|
|
|
1163
|
|
|
|
|
|
|
=item Rob Kinyon |
|
1164
|
|
|
|
|
|
|
|
|
1165
|
|
|
|
|
|
|
Thanks to Rob for actually getting the development of this module kick-started. |
|
1166
|
|
|
|
|
|
|
|
|
1167
|
|
|
|
|
|
|
=back |
|
1168
|
|
|
|
|
|
|
|
|
1169
|
|
|
|
|
|
|
=head1 AUTHORS |
|
1170
|
|
|
|
|
|
|
|
|
1171
|
|
|
|
|
|
|
=over 4 |
|
1172
|
|
|
|
|
|
|
|
|
1173
|
|
|
|
|
|
|
=item * |
|
1174
|
|
|
|
|
|
|
|
|
1175
|
|
|
|
|
|
|
Stevan Little <stevan@cpan.org> |
|
1176
|
|
|
|
|
|
|
|
|
1177
|
|
|
|
|
|
|
=item * |
|
1178
|
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
Dave Rolsky <autarch@urth.org> |
|
1180
|
|
|
|
|
|
|
|
|
1181
|
|
|
|
|
|
|
=item * |
|
1182
|
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
Jesse Luehrs <doy@cpan.org> |
|
1184
|
|
|
|
|
|
|
|
|
1185
|
|
|
|
|
|
|
=item * |
|
1186
|
|
|
|
|
|
|
|
|
1187
|
|
|
|
|
|
|
Shawn M Moore <sartak@cpan.org> |
|
1188
|
|
|
|
|
|
|
|
|
1189
|
|
|
|
|
|
|
=item * |
|
1190
|
|
|
|
|
|
|
|
|
1191
|
|
|
|
|
|
|
יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org> |
|
1192
|
|
|
|
|
|
|
|
|
1193
|
|
|
|
|
|
|
=item * |
|
1194
|
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
Karen Etheridge <ether@cpan.org> |
|
1196
|
|
|
|
|
|
|
|
|
1197
|
|
|
|
|
|
|
=item * |
|
1198
|
|
|
|
|
|
|
|
|
1199
|
|
|
|
|
|
|
Florian Ragwitz <rafl@debian.org> |
|
1200
|
|
|
|
|
|
|
|
|
1201
|
|
|
|
|
|
|
=item * |
|
1202
|
|
|
|
|
|
|
|
|
1203
|
|
|
|
|
|
|
Hans Dieter Pearcey <hdp@cpan.org> |
|
1204
|
|
|
|
|
|
|
|
|
1205
|
|
|
|
|
|
|
=item * |
|
1206
|
|
|
|
|
|
|
|
|
1207
|
|
|
|
|
|
|
Chris Prather <chris@prather.org> |
|
1208
|
|
|
|
|
|
|
|
|
1209
|
|
|
|
|
|
|
=item * |
|
1210
|
|
|
|
|
|
|
|
|
1211
|
|
|
|
|
|
|
Matt S Trout <mstrout@cpan.org> |
|
1212
|
|
|
|
|
|
|
|
|
1213
|
|
|
|
|
|
|
=back |
|
1214
|
|
|
|
|
|
|
|
|
1215
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
|
1216
|
|
|
|
|
|
|
|
|
1217
|
|
|
|
|
|
|
This software is copyright (c) 2006 by Infinity Interactive, Inc. |
|
1218
|
|
|
|
|
|
|
|
|
1219
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
|
1220
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
|
1221
|
|
|
|
|
|
|
|
|
1222
|
|
|
|
|
|
|
=cut |