line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Class::MOP; |
2
|
|
|
|
|
|
|
our $VERSION = '2.2205'; |
3
|
|
|
|
|
|
|
|
4
|
450
|
|
|
450
|
|
4562693
|
use strict; |
|
450
|
|
|
|
|
1686
|
|
|
450
|
|
|
|
|
15142
|
|
5
|
450
|
|
|
450
|
|
2413
|
use warnings; |
|
450
|
|
|
|
|
1007
|
|
|
450
|
|
|
|
|
11481
|
|
6
|
|
|
|
|
|
|
|
7
|
450
|
|
|
450
|
|
9015
|
use 5.008003; |
|
450
|
|
|
|
|
1724
|
|
8
|
|
|
|
|
|
|
|
9
|
450
|
|
|
450
|
|
224764
|
use MRO::Compat; |
|
450
|
|
|
|
|
827180
|
|
|
450
|
|
|
|
|
15384
|
|
10
|
450
|
|
|
450
|
|
67283
|
use Class::Load 0.07 (); |
|
450
|
|
|
|
|
1868257
|
|
|
450
|
|
|
|
|
11975
|
|
11
|
450
|
|
|
450
|
|
2708
|
use Scalar::Util 'weaken', 'isweak', 'blessed'; |
|
450
|
|
|
|
|
1225
|
|
|
450
|
|
|
|
|
23923
|
|
12
|
450
|
|
|
450
|
|
4785
|
use Data::OptList; |
|
450
|
|
|
|
|
1904
|
|
|
450
|
|
|
|
|
3067
|
|
13
|
|
|
|
|
|
|
|
14
|
450
|
|
|
450
|
|
220325
|
use Class::MOP::Mixin::AttributeCore; |
|
450
|
|
|
|
|
1198
|
|
|
450
|
|
|
|
|
14011
|
|
15
|
450
|
|
|
450
|
|
201180
|
use Class::MOP::Mixin::HasAttributes; |
|
450
|
|
|
|
|
1230
|
|
|
450
|
|
|
|
|
14174
|
|
16
|
450
|
|
|
450
|
|
206863
|
use Class::MOP::Mixin::HasMethods; |
|
450
|
|
|
|
|
1563
|
|
|
450
|
|
|
|
|
14417
|
|
17
|
450
|
|
|
450
|
|
212535
|
use Class::MOP::Mixin::HasOverloads; |
|
450
|
|
|
|
|
1252
|
|
|
450
|
|
|
|
|
13083
|
|
18
|
450
|
|
|
450
|
|
309871
|
use Class::MOP::Class; |
|
450
|
|
|
|
|
1625
|
|
|
450
|
|
|
|
|
24907
|
|
19
|
450
|
|
|
450
|
|
261446
|
use Class::MOP::Attribute; |
|
450
|
|
|
|
|
1340
|
|
|
450
|
|
|
|
|
14972
|
|
20
|
450
|
|
|
450
|
|
5928
|
use Class::MOP::Method; |
|
450
|
|
|
|
|
1137
|
|
|
450
|
|
|
|
|
39704
|
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
BEGIN { |
23
|
|
|
|
|
|
|
*IS_RUNNING_ON_5_10 = ("$]" < 5.009_005) |
24
|
|
|
|
|
|
|
? sub () { 0 } |
25
|
450
|
50
|
|
450
|
|
4965
|
: sub () { 1 }; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# this is either part of core or set up appropriately by MRO::Compat |
28
|
450
|
|
|
|
|
1121199
|
*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
|
294
|
sub get_all_metaclasses { %METAS } |
45
|
4
|
|
|
4
|
1
|
60
|
sub get_all_metaclass_instances { values %METAS } |
46
|
1
|
|
|
1
|
1
|
11
|
sub get_all_metaclass_names { keys %METAS } |
47
|
746457
|
|
|
746457
|
1
|
3399490
|
sub get_metaclass_by_name { $METAS{$_[0]} } |
48
|
31809
|
|
|
31809
|
1
|
110076
|
sub store_metaclass_by_name { $METAS{$_[0]} = $_[1] } |
49
|
117
|
|
|
117
|
1
|
673
|
sub weaken_metaclass { weaken($METAS{$_[0]}) } |
50
|
35187
|
|
|
35187
|
1
|
139038
|
sub metaclass_is_weak { isweak($METAS{$_[0]}) } |
51
|
22583
|
100
|
|
22583
|
1
|
155325
|
sub does_metaclass_exist { exists $METAS{$_[0]} && defined $METAS{$_[0]} } |
52
|
270
|
|
|
270
|
1
|
14789
|
sub remove_metaclass_by_name { delete $METAS{$_[0]}; return } |
|
270
|
|
|
|
|
695
|
|
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# This handles instances as well as class names |
55
|
|
|
|
|
|
|
sub class_of { |
56
|
38772
|
100
|
|
38772
|
1
|
114369
|
return unless defined $_[0]; |
57
|
38768
|
|
66
|
|
|
142839
|
my $class = blessed($_[0]) || $_[0]; |
58
|
38768
|
|
|
|
|
117181
|
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
|
181
|
Class::MOP::Deprecated::deprecated( |
70
|
|
|
|
|
|
|
message => 'Class::MOP::load_class is deprecated', |
71
|
|
|
|
|
|
|
feature => 'Class::Load wrapper functions', |
72
|
|
|
|
|
|
|
); |
73
|
1
|
|
|
|
|
286
|
require Class::Load; |
74
|
1
|
|
|
|
|
11
|
goto &Class::Load::load_class; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub load_first_existing_class { |
78
|
1
|
|
|
1
|
0
|
584
|
Class::MOP::Deprecated::deprecated( |
79
|
|
|
|
|
|
|
message => 'Class::MOP::load_first_existing_class is deprecated', |
80
|
|
|
|
|
|
|
feature => 'Class::Load wrapper functions', |
81
|
|
|
|
|
|
|
); |
82
|
1
|
|
|
|
|
173
|
require Class::Load; |
83
|
1
|
|
|
|
|
10
|
goto &Class::Load::load_first_existing_class; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub is_class_loaded { |
87
|
1
|
|
|
1
|
0
|
287
|
Class::MOP::Deprecated::deprecated( |
88
|
|
|
|
|
|
|
message => 'Class::MOP::is_class_loaded is deprecated', |
89
|
|
|
|
|
|
|
feature => 'Class::Load wrapper functions', |
90
|
|
|
|
|
|
|
); |
91
|
1
|
|
|
|
|
178
|
require Class::Load; |
92
|
1
|
|
|
|
|
8
|
goto &Class::Load::is_class_loaded; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub _definition_context { |
96
|
54335
|
|
|
54335
|
|
87129
|
my %context; |
97
|
54335
|
|
|
|
|
420018
|
@context{qw(package file line)} = caller(0); |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
return ( |
100
|
54335
|
|
|
|
|
307593
|
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
|
|
7041
|
my $self = shift; |
506
|
6
|
|
|
|
|
28
|
$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.2205 |
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 |