Tweaks to class_of
[gitmo/Class-MOP.git] / lib / Class / MOP.pm
CommitLineData
94b19069 1
2package Class::MOP;
3
4use strict;
5use warnings;
6
5a2932cf 7use 5.008;
8
3cf322a0 9use MRO::Compat;
10
4c105333 11use Carp 'confess';
4bfa5ddb 12use Devel::GlobalDestruction qw( in_global_destruction );
b1a46f91 13use Scalar::Util 'weaken', 'reftype', 'blessed';
4bfa5ddb 14use Sub::Name qw( subname );
fc4f8f91 15
0531f510 16use Class::MOP::Class;
17use Class::MOP::Attribute;
18use Class::MOP::Method;
19
20use Class::MOP::Immutable;
21
b1f5f41d 22BEGIN {
11b56828 23 *IS_RUNNING_ON_5_10 = ($] < 5.009_005)
24 ? sub () { 0 }
4c105333 25 : sub () { 1 };
46b23b44 26
9efe16ca 27 *HAVE_ISAREV = defined(&mro::get_isarev)
28 ? sub () { 1 }
29 : sub () { 1 };
3ecd1b25 30
31 # this is either part of core or set up appropriately by MRO::Compat
32 *check_package_cache_flag = \&mro::get_pkg_gen;
b1f5f41d 33}
e0e4674a 34
d7fe2508 35our $VERSION = '0.79';
8a7085c1 36our $XS_VERSION = $VERSION;
d519662a 37$VERSION = eval $VERSION;
fc4f8f91 38our $AUTHORITY = 'cpan:STEVAN';
9d655b6d 39
4bfa5ddb 40require XSLoader;
41XSLoader::load( __PACKAGE__, $XS_VERSION );
d7bda114 42
43
be7677c7 44{
45 # Metaclasses are singletons, so we cache them here.
46 # there is no need to worry about destruction though
47 # because they should die only when the program dies.
48 # After all, do package definitions even get reaped?
1d68af04 49 my %METAS;
50
51 # means of accessing all the metaclasses that have
be7677c7 52 # been initialized thus far (for mugwumps obj browser)
1d68af04 53 sub get_all_metaclasses { %METAS }
54 sub get_all_metaclass_instances { values %METAS }
55 sub get_all_metaclass_names { keys %METAS }
be7677c7 56 sub get_metaclass_by_name { $METAS{$_[0]} }
1d68af04 57 sub store_metaclass_by_name { $METAS{$_[0]} = $_[1] }
58 sub weaken_metaclass { weaken($METAS{$_[0]}) }
be7677c7 59 sub does_metaclass_exist { exists $METAS{$_[0]} && defined $METAS{$_[0]} }
1d68af04 60 sub remove_metaclass_by_name { $METAS{$_[0]} = undef }
61
be7677c7 62 # NOTE:
1d68af04 63 # We only cache metaclasses, meaning instances of
64 # Class::MOP::Class. We do not cache instance of
be7677c7 65 # Class::MOP::Package or Class::MOP::Module. Mostly
1d68af04 66 # because I don't yet see a good reason to do so.
be7677c7 67}
68
063ad0c5 69sub load_first_existing_class {
f280f05c 70 my @classes = @_
71 or return;
5a24cf8a 72
73 foreach my $class (@classes) {
74 unless ( _is_valid_class_name($class) ) {
75 my $display = defined($class) ? $class : 'undef';
76 confess "Invalid class name ($display)";
77 }
ab5e2f48 78 }
79
063ad0c5 80 my $found;
5a24cf8a 81 my %exceptions;
063ad0c5 82 for my $class (@classes) {
83 my $e = _try_load_one_class($class);
84
5a24cf8a 85 if ($e) {
063ad0c5 86 $exceptions{$class} = $e;
5a24cf8a 87 }
88 else {
063ad0c5 89 $found = $class;
90 last;
5a24cf8a 91 }
063ad0c5 92 }
5a24cf8a 93
1d8153bd 94 return $found if $found;
07940968 95
063ad0c5 96 confess join(
97 "\n",
98 map {
99 sprintf(
fea44045 100 "Could not load class (%s) because : %s", $_,
063ad0c5 101 $exceptions{$_}
102 )
103 } @classes
f280f05c 104 );
5a24cf8a 105}
106
063ad0c5 107sub _try_load_one_class {
108 my $class = shift;
109
110 return if is_class_loaded($class);
111
112 my $file = $class . '.pm';
113 $file =~ s{::}{/}g;
114
115 return do {
116 local $@;
117 eval { require($file) };
118 $@;
119 };
120}
121
5a24cf8a 122sub load_class {
1d8153bd 123 my $class = load_first_existing_class($_[0]);
124 return get_metaclass_by_name($class) || $class;
448b6e55 125}
126
2c0fb064 127sub _is_valid_class_name {
128 my $class = shift;
129
130 return 0 if ref($class);
131 return 0 unless defined($class);
132 return 0 unless length($class);
133
134 return 1 if $class =~ /^\w+(?:::\w+)*$/;
135
136 return 0;
137}
138
53e90873 139sub class_of {
140 my $self = shift;
141 my $class = shift;
142
b1a46f91 143 return undef if !defined($class);
144
53e90873 145 $class = blessed($class) || $class;
146
147 return get_metaclass_by_name($class);
148}
149
aa448b16 150## ----------------------------------------------------------------------------
151## Setting up our environment ...
152## ----------------------------------------------------------------------------
1d68af04 153## Class::MOP needs to have a few things in the global perl environment so
aa448b16 154## that it can operate effectively. Those things are done here.
155## ----------------------------------------------------------------------------
156
3bf7644b 157# ... nothing yet actually ;)
8b978dd5 158
b51af7f9 159## ----------------------------------------------------------------------------
1d68af04 160## Bootstrapping
b51af7f9 161## ----------------------------------------------------------------------------
1d68af04 162## The code below here is to bootstrap our MOP with itself. This is also
b51af7f9 163## sometimes called "tying the knot". By doing this, we make it much easier
164## to extend the MOP through subclassing and such since now you can use the
1d68af04 165## MOP itself to extend itself.
166##
b51af7f9 167## Yes, I know, thats weird and insane, but it's a good thing, trust me :)
1d68af04 168## ----------------------------------------------------------------------------
727919c5 169
1d68af04 170# We need to add in the meta-attributes here so that
171# any subclass of Class::MOP::* will be able to
727919c5 172# inherit them using &construct_instance
173
f0480c45 174## --------------------------------------------------------
6d5355c3 175## Class::MOP::Package
727919c5 176
6d5355c3 177Class::MOP::Package->meta->add_attribute(
8683db0e 178 Class::MOP::Attribute->new('package' => (
b880e0de 179 reader => {
1d68af04 180 # NOTE: we need to do this in order
181 # for the instance meta-object to
b880e0de 182 # not fall into meta-circular death
1d68af04 183 #
ce2ae40f 184 # we just alias the original method
1d68af04 185 # rather than re-produce it here
ce2ae40f 186 'name' => \&Class::MOP::Package::name
b880e0de 187 },
727919c5 188 ))
189);
190
a5e51f0b 191Class::MOP::Package->meta->add_attribute(
8683db0e 192 Class::MOP::Attribute->new('namespace' => (
a5e51f0b 193 reader => {
56dcfc1a 194 # NOTE:
ce2ae40f 195 # we just alias the original method
196 # rather than re-produce it here
197 'namespace' => \&Class::MOP::Package::namespace
a5e51f0b 198 },
2e877f58 199 init_arg => undef,
c4260b45 200 default => sub { \undef }
a5e51f0b 201 ))
202);
203
f0480c45 204## --------------------------------------------------------
205## Class::MOP::Module
206
207# NOTE:
1d68af04 208# yeah this is kind of stretching things a bit,
f0480c45 209# but truthfully the version should be an attribute
1d68af04 210# of the Module, the weirdness comes from having to
211# stick to Perl 5 convention and store it in the
212# $VERSION package variable. Basically if you just
213# squint at it, it will look how you want it to look.
f0480c45 214# Either as a package variable, or as a attribute of
215# the metaclass, isn't abstraction great :)
216
217Class::MOP::Module->meta->add_attribute(
8683db0e 218 Class::MOP::Attribute->new('version' => (
f0480c45 219 reader => {
ce2ae40f 220 # NOTE:
221 # we just alias the original method
1d68af04 222 # rather than re-produce it here
ce2ae40f 223 'version' => \&Class::MOP::Module::version
f0480c45 224 },
2e877f58 225 init_arg => undef,
c4260b45 226 default => sub { \undef }
f0480c45 227 ))
228);
229
230# NOTE:
1d68af04 231# By following the same conventions as version here,
232# we are opening up the possibility that people can
233# use the $AUTHORITY in non-Class::MOP modules as
234# well.
f0480c45 235
236Class::MOP::Module->meta->add_attribute(
8683db0e 237 Class::MOP::Attribute->new('authority' => (
f0480c45 238 reader => {
ce2ae40f 239 # NOTE:
240 # we just alias the original method
1d68af04 241 # rather than re-produce it here
ce2ae40f 242 'authority' => \&Class::MOP::Module::authority
1d68af04 243 },
2e877f58 244 init_arg => undef,
c4260b45 245 default => sub { \undef }
f0480c45 246 ))
247);
248
249## --------------------------------------------------------
6d5355c3 250## Class::MOP::Class
251
727919c5 252Class::MOP::Class->meta->add_attribute(
8683db0e 253 Class::MOP::Attribute->new('attributes' => (
f7259199 254 reader => {
1d68af04 255 # NOTE: we need to do this in order
256 # for the instance meta-object to
257 # not fall into meta-circular death
258 #
ce2ae40f 259 # we just alias the original method
1d68af04 260 # rather than re-produce it here
ce2ae40f 261 'get_attribute_map' => \&Class::MOP::Class::get_attribute_map
f7259199 262 },
727919c5 263 default => sub { {} }
264 ))
265);
266
351bd7d4 267Class::MOP::Class->meta->add_attribute(
8683db0e 268 Class::MOP::Attribute->new('methods' => (
1d68af04 269 reader => {
ce2ae40f 270 # NOTE:
271 # we just alias the original method
1d68af04 272 # rather than re-produce it here
ce2ae40f 273 'get_method_map' => \&Class::MOP::Class::get_method_map
92330ee2 274 },
7855ddba 275 default => sub { {} }
c4260b45 276 ))
277);
278
279Class::MOP::Class->meta->add_attribute(
8683db0e 280 Class::MOP::Attribute->new('superclasses' => (
c23184fc 281 accessor => {
282 # NOTE:
283 # we just alias the original method
1d68af04 284 # rather than re-produce it here
c23184fc 285 'superclasses' => \&Class::MOP::Class::superclasses
286 },
2e877f58 287 init_arg => undef,
c23184fc 288 default => sub { \undef }
289 ))
290);
291
292Class::MOP::Class->meta->add_attribute(
8683db0e 293 Class::MOP::Attribute->new('attribute_metaclass' => (
1d68af04 294 reader => {
6d2118a4 295 # NOTE:
296 # we just alias the original method
1d68af04 297 # rather than re-produce it here
6d2118a4 298 'attribute_metaclass' => \&Class::MOP::Class::attribute_metaclass
1d68af04 299 },
351bd7d4 300 default => 'Class::MOP::Attribute',
301 ))
302);
303
304Class::MOP::Class->meta->add_attribute(
8683db0e 305 Class::MOP::Attribute->new('method_metaclass' => (
1d68af04 306 reader => {
6d2118a4 307 # NOTE:
308 # we just alias the original method
1d68af04 309 # rather than re-produce it here
6d2118a4 310 'method_metaclass' => \&Class::MOP::Class::method_metaclass
311 },
1d68af04 312 default => 'Class::MOP::Method',
351bd7d4 313 ))
314);
315
2bab2be6 316Class::MOP::Class->meta->add_attribute(
77373da8 317 Class::MOP::Attribute->new('wrapped_method_metaclass' => (
318 reader => {
319 # NOTE:
320 # we just alias the original method
321 # rather than re-produce it here
322 'wrapped_method_metaclass' => \&Class::MOP::Class::wrapped_method_metaclass
323 },
324 default => 'Class::MOP::Method::Wrapped',
325 ))
326);
327
328Class::MOP::Class->meta->add_attribute(
8683db0e 329 Class::MOP::Attribute->new('instance_metaclass' => (
b880e0de 330 reader => {
1d68af04 331 # NOTE: we need to do this in order
332 # for the instance meta-object to
333 # not fall into meta-circular death
334 #
ce2ae40f 335 # we just alias the original method
1d68af04 336 # rather than re-produce it here
ce2ae40f 337 'instance_metaclass' => \&Class::MOP::Class::instance_metaclass
b880e0de 338 },
1d68af04 339 default => 'Class::MOP::Instance',
2bab2be6 340 ))
341);
342
44d6ea77 343Class::MOP::Class->meta->add_attribute(
344 Class::MOP::Attribute->new('immutable_transformer' => (
345 reader => {
346 'immutable_transformer' => \&Class::MOP::Class::immutable_transformer
347 },
348 writer => {
349 '_set_immutable_transformer' => \&Class::MOP::Class::_set_immutable_transformer
350 },
351 ))
352);
353
9d6dce77 354# NOTE:
1d68af04 355# we don't actually need to tie the knot with
356# Class::MOP::Class here, it is actually handled
357# within Class::MOP::Class itself in the
358# construct_class_instance method.
9d6dce77 359
f0480c45 360## --------------------------------------------------------
727919c5 361## Class::MOP::Attribute
362
7b31baf4 363Class::MOP::Attribute->meta->add_attribute(
8683db0e 364 Class::MOP::Attribute->new('name' => (
c23184fc 365 reader => {
1d68af04 366 # NOTE: we need to do this in order
367 # for the instance meta-object to
368 # not fall into meta-circular death
369 #
ce2ae40f 370 # we just alias the original method
1d68af04 371 # rather than re-produce it here
ce2ae40f 372 'name' => \&Class::MOP::Attribute::name
b880e0de 373 }
7b31baf4 374 ))
375);
376
377Class::MOP::Attribute->meta->add_attribute(
8683db0e 378 Class::MOP::Attribute->new('associated_class' => (
c23184fc 379 reader => {
1d68af04 380 # NOTE: we need to do this in order
381 # for the instance meta-object to
382 # not fall into meta-circular death
383 #
ce2ae40f 384 # we just alias the original method
1d68af04 385 # rather than re-produce it here
ce2ae40f 386 'associated_class' => \&Class::MOP::Attribute::associated_class
b880e0de 387 }
7b31baf4 388 ))
389);
390
391Class::MOP::Attribute->meta->add_attribute(
8683db0e 392 Class::MOP::Attribute->new('accessor' => (
6d2118a4 393 reader => { 'accessor' => \&Class::MOP::Attribute::accessor },
394 predicate => { 'has_accessor' => \&Class::MOP::Attribute::has_accessor },
7b31baf4 395 ))
396);
397
398Class::MOP::Attribute->meta->add_attribute(
8683db0e 399 Class::MOP::Attribute->new('reader' => (
6d2118a4 400 reader => { 'reader' => \&Class::MOP::Attribute::reader },
401 predicate => { 'has_reader' => \&Class::MOP::Attribute::has_reader },
7b31baf4 402 ))
403);
404
405Class::MOP::Attribute->meta->add_attribute(
8683db0e 406 Class::MOP::Attribute->new('initializer' => (
8ee74136 407 reader => { 'initializer' => \&Class::MOP::Attribute::initializer },
408 predicate => { 'has_initializer' => \&Class::MOP::Attribute::has_initializer },
0ab65f99 409 ))
410);
411
412Class::MOP::Attribute->meta->add_attribute(
d9d99689 413 Class::MOP::Attribute->new('definition_context' => (
414 reader => { 'definition_context' => \&Class::MOP::Attribute::definition_context },
415 ))
416);
417
418Class::MOP::Attribute->meta->add_attribute(
8683db0e 419 Class::MOP::Attribute->new('writer' => (
6d2118a4 420 reader => { 'writer' => \&Class::MOP::Attribute::writer },
421 predicate => { 'has_writer' => \&Class::MOP::Attribute::has_writer },
7b31baf4 422 ))
423);
424
425Class::MOP::Attribute->meta->add_attribute(
8683db0e 426 Class::MOP::Attribute->new('predicate' => (
6d2118a4 427 reader => { 'predicate' => \&Class::MOP::Attribute::predicate },
428 predicate => { 'has_predicate' => \&Class::MOP::Attribute::has_predicate },
7b31baf4 429 ))
430);
431
432Class::MOP::Attribute->meta->add_attribute(
8683db0e 433 Class::MOP::Attribute->new('clearer' => (
6d2118a4 434 reader => { 'clearer' => \&Class::MOP::Attribute::clearer },
435 predicate => { 'has_clearer' => \&Class::MOP::Attribute::has_clearer },
7d28758b 436 ))
437);
438
439Class::MOP::Attribute->meta->add_attribute(
8683db0e 440 Class::MOP::Attribute->new('builder' => (
1d68af04 441 reader => { 'builder' => \&Class::MOP::Attribute::builder },
442 predicate => { 'has_builder' => \&Class::MOP::Attribute::has_builder },
443 ))
444);
445
446Class::MOP::Attribute->meta->add_attribute(
8683db0e 447 Class::MOP::Attribute->new('init_arg' => (
6d2118a4 448 reader => { 'init_arg' => \&Class::MOP::Attribute::init_arg },
449 predicate => { 'has_init_arg' => \&Class::MOP::Attribute::has_init_arg },
7b31baf4 450 ))
451);
452
453Class::MOP::Attribute->meta->add_attribute(
8683db0e 454 Class::MOP::Attribute->new('default' => (
7b31baf4 455 # default has a custom 'reader' method ...
1d68af04 456 predicate => { 'has_default' => \&Class::MOP::Attribute::has_default },
7b31baf4 457 ))
458);
459
3545c727 460Class::MOP::Attribute->meta->add_attribute(
8683db0e 461 Class::MOP::Attribute->new('associated_methods' => (
c23184fc 462 reader => { 'associated_methods' => \&Class::MOP::Attribute::associated_methods },
1d68af04 463 default => sub { [] }
3545c727 464 ))
465);
727919c5 466
5659d76e 467Class::MOP::Attribute->meta->add_method('clone' => sub {
a740253a 468 my $self = shift;
1d68af04 469 $self->meta->clone_object($self, @_);
727919c5 470});
471
f0480c45 472## --------------------------------------------------------
b6164407 473## Class::MOP::Method
b6164407 474Class::MOP::Method->meta->add_attribute(
8683db0e 475 Class::MOP::Attribute->new('body' => (
c23184fc 476 reader => { 'body' => \&Class::MOP::Method::body },
b6164407 477 ))
478);
479
4c105333 480Class::MOP::Method->meta->add_attribute(
5e607260 481 Class::MOP::Attribute->new('associated_metaclass' => (
5e607260 482 reader => { 'associated_metaclass' => \&Class::MOP::Method::associated_metaclass },
483 ))
484);
485
486Class::MOP::Method->meta->add_attribute(
8683db0e 487 Class::MOP::Attribute->new('package_name' => (
4c105333 488 reader => { 'package_name' => \&Class::MOP::Method::package_name },
489 ))
490);
491
492Class::MOP::Method->meta->add_attribute(
8683db0e 493 Class::MOP::Attribute->new('name' => (
4c105333 494 reader => { 'name' => \&Class::MOP::Method::name },
495 ))
496);
497
2226a8b0 498Class::MOP::Method->meta->add_attribute(
499 Class::MOP::Attribute->new('original_method' => (
500 reader => { 'original_method' => \&Class::MOP::Method::original_method },
501 writer => { '_set_original_method' => \&Class::MOP::Method::_set_original_method },
502 ))
503);
504
4c105333 505Class::MOP::Method->meta->add_method('clone' => sub {
506 my $self = shift;
2226a8b0 507 my $clone = $self->meta->clone_object($self, @_);
508 $clone->_set_original_method($self);
509 return $clone;
4c105333 510});
511
b6164407 512## --------------------------------------------------------
513## Class::MOP::Method::Wrapped
514
515# NOTE:
1d68af04 516# the way this item is initialized, this
517# really does not follow the standard
518# practices of attributes, but we put
b6164407 519# it here for completeness
520Class::MOP::Method::Wrapped->meta->add_attribute(
8683db0e 521 Class::MOP::Attribute->new('modifier_table')
b6164407 522);
523
524## --------------------------------------------------------
565f0cbb 525## Class::MOP::Method::Generated
526
527Class::MOP::Method::Generated->meta->add_attribute(
8683db0e 528 Class::MOP::Attribute->new('is_inline' => (
565f0cbb 529 reader => { 'is_inline' => \&Class::MOP::Method::Generated::is_inline },
4c105333 530 default => 0,
1d68af04 531 ))
565f0cbb 532);
533
d9d99689 534Class::MOP::Method::Generated->meta->add_attribute(
535 Class::MOP::Attribute->new('definition_context' => (
536 reader => { 'definition_context' => \&Class::MOP::Method::Generated::definition_context },
537 ))
538);
539
565f0cbb 540## --------------------------------------------------------
d90b42a6 541## Class::MOP::Method::Accessor
542
543Class::MOP::Method::Accessor->meta->add_attribute(
8683db0e 544 Class::MOP::Attribute->new('attribute' => (
1d68af04 545 reader => {
546 'associated_attribute' => \&Class::MOP::Method::Accessor::associated_attribute
d90b42a6 547 },
1d68af04 548 ))
d90b42a6 549);
550
551Class::MOP::Method::Accessor->meta->add_attribute(
8683db0e 552 Class::MOP::Attribute->new('accessor_type' => (
c23184fc 553 reader => { 'accessor_type' => \&Class::MOP::Method::Accessor::accessor_type },
1d68af04 554 ))
d90b42a6 555);
556
d90b42a6 557## --------------------------------------------------------
558## Class::MOP::Method::Constructor
559
560Class::MOP::Method::Constructor->meta->add_attribute(
8683db0e 561 Class::MOP::Attribute->new('options' => (
1d68af04 562 reader => {
563 'options' => \&Class::MOP::Method::Constructor::options
d90b42a6 564 },
4c105333 565 default => sub { +{} }
1d68af04 566 ))
d90b42a6 567);
568
569Class::MOP::Method::Constructor->meta->add_attribute(
8683db0e 570 Class::MOP::Attribute->new('associated_metaclass' => (
e8a38403 571 init_arg => "metaclass", # FIXME alias and rename
1d68af04 572 reader => {
573 'associated_metaclass' => \&Class::MOP::Method::Constructor::associated_metaclass
574 },
575 ))
d90b42a6 576);
577
578## --------------------------------------------------------
86482605 579## Class::MOP::Instance
580
581# NOTE:
1d68af04 582# these don't yet do much of anything, but are just
86482605 583# included for completeness
584
585Class::MOP::Instance->meta->add_attribute(
74890687 586 Class::MOP::Attribute->new('associated_metaclass',
587 reader => { associated_metaclass => \&Class::MOP::Instance::associated_metaclass },
588 ),
86482605 589);
590
591Class::MOP::Instance->meta->add_attribute(
74890687 592 Class::MOP::Attribute->new('_class_name',
593 init_arg => undef,
594 reader => { _class_name => \&Class::MOP::Instance::_class_name },
595 #lazy => 1, # not yet supported by Class::MOP but out our version does it anyway
596 #default => sub { $_[0]->associated_metaclass->name },
597 ),
598);
599
600Class::MOP::Instance->meta->add_attribute(
601 Class::MOP::Attribute->new('attributes',
0b5d46da 602 reader => { attributes => \&Class::MOP::Instance::get_all_attributes },
74890687 603 ),
32bfc810 604);
605
606Class::MOP::Instance->meta->add_attribute(
74890687 607 Class::MOP::Attribute->new('slots',
608 reader => { slots => \&Class::MOP::Instance::slots },
609 ),
86482605 610);
611
63d08a9e 612Class::MOP::Instance->meta->add_attribute(
74890687 613 Class::MOP::Attribute->new('slot_hash',
614 reader => { slot_hash => \&Class::MOP::Instance::slot_hash },
615 ),
63d08a9e 616);
617
618
caa051fa 619# we need the meta instance of the meta instance to be created now, in order
620# for the constructor to be able to use it
621Class::MOP::Instance->meta->get_meta_instance;
622
caa051fa 623# pretend the add_method never happenned. it hasn't yet affected anything
624undef Class::MOP::Instance->meta->{_package_cache_flag};
625
86482605 626## --------------------------------------------------------
f0480c45 627## Now close all the Class::MOP::* classes
4d47b77f 628
1aa13cf4 629# NOTE: we don't need to inline the the accessors this only lengthens
630# the compile time of the MOP, and gives us no actual benefits.
0b9372a2 631
632$_->meta->make_immutable(
6c2f6b5c 633 inline_constructor => 1,
634 replace_constructor => 1,
635 constructor_name => "_new",
45582002 636 inline_accessors => 0,
0b9372a2 637) for qw/
1d68af04 638 Class::MOP::Package
639 Class::MOP::Module
640 Class::MOP::Class
641
0b9372a2 642 Class::MOP::Attribute
1d68af04 643 Class::MOP::Method
644 Class::MOP::Instance
645
646 Class::MOP::Object
0b9372a2 647
565f0cbb 648 Class::MOP::Method::Generated
1d68af04 649
ba38bf08 650 Class::MOP::Method::Accessor
1d68af04 651 Class::MOP::Method::Constructor
652 Class::MOP::Method::Wrapped
0b9372a2 653/;
b6164407 654
94b19069 6551;
656
657__END__
658
659=pod
660
1d68af04 661=head1 NAME
94b19069 662
663Class::MOP - A Meta Object Protocol for Perl 5
664
5b60bf98 665=head1 DESCRIPTION
94b19069 666
127d39a7 667This module is a fully functioning meta object protocol for the
1d68af04 668Perl 5 object system. It makes no attempt to change the behavior or
669characteristics of the Perl 5 object system, only to create a
27e31eaf 670protocol for its manipulation and introspection.
94b19069 671
828ecf13 672That said, it does attempt to create the tools for building a rich set
673of extensions to the Perl 5 object system. Every attempt has been made
674to abide by the spirit of the Perl 5 object system that we all know
675and love.
94b19069 676
828ecf13 677This documentation is sparse on conceptual details. We suggest looking
678at the items listed in the L<SEE ALSO> section for more
679information. In particular the book "The Art of the Meta Object
680Protocol" was very influential in the development of this system.
40483095 681
bfe4d0fc 682=head2 What is a Meta Object Protocol?
683
1d68af04 684A meta object protocol is an API to an object system.
bfe4d0fc 685
828ecf13 686To be more specific, it abstracts the components of an object system
687(classes, object, methods, object attributes, etc.). These
688abstractions can then be used to inspect and manipulate the object
689system which they describe.
bfe4d0fc 690
1d68af04 691It can be said that there are two MOPs for any object system; the
828ecf13 692implicit MOP and the explicit MOP. The implicit MOP handles things
1d68af04 693like method dispatch or inheritance, which happen automatically as
694part of how the object system works. The explicit MOP typically
695handles the introspection/reflection features of the object system.
bfe4d0fc 696
828ecf13 697All object systems have implicit MOPs. Without one, they would not
5b60bf98 698work. Explicit MOPs are much less common, and depending on the
699language can vary from restrictive (Reflection in Java or C#) to wide
700open (CLOS is a perfect example).
e16da3e6 701
828ecf13 702=head2 Yet Another Class Builder! Why?
703
704This is B<not> a class builder so much as a I<class builder
705B<builder>>. The intent is that an end user will not use this module
706directly, but instead this module is used by module authors to build
707extensions and features onto the Perl 5 object system.
708
709This system is used by L<Moose>, which supplies a powerful class
710builder system built entirely on top of C<Class::MOP>.
e16da3e6 711
94b19069 712=head2 Who is this module for?
713
828ecf13 714This module is for anyone who has ever created or wanted to create a
715module for the Class:: namespace. The tools which this module provides
716make doing complex Perl 5 wizardry simpler, by removing such barriers
717as the need to hack symbol tables, or understand the fine details of
718method dispatch.
94b19069 719
bfe4d0fc 720=head2 What changes do I have to make to use this module?
721
828ecf13 722This module was designed to be as unintrusive as possible. Many of its
5b60bf98 723features are accessible without B<any> change to your existing
828ecf13 724code. It is meant to be a compliment to your existing code and not an
725intrusion on your code base. Unlike many other B<Class::> modules,
726this module B<does not> require you subclass it, or even that you
727C<use> it in within your module's package.
bfe4d0fc 728
1d68af04 729The only features which requires additions to your code are the
2eb717d5 730attribute handling and instance construction features, and these are
1d68af04 731both completely optional features. The only reason for this is because
732Perl 5's object system does not actually have these features built
2eb717d5 733in. More information about this feature can be found below.
bfe4d0fc 734
828ecf13 735=head2 About Performance
736
5b60bf98 737It is a common misconception that explicit MOPs are a performance hit.
828ecf13 738This is not a universal truth, it is a side-effect of some specific
739implementations. For instance, using Java reflection is slow because
740the JVM cannot take advantage of any compiler optimizations, and the
741JVM has to deal with much more runtime type information as well.
bfe4d0fc 742
828ecf13 743Reflection in C# is marginally better as it was designed into the
744language and runtime (the CLR). In contrast, CLOS (the Common Lisp
745Object System) was built to support an explicit MOP, and so
746performance is tuned for it.
1d68af04 747
828ecf13 748This library in particular does its absolute best to avoid putting
1d68af04 749B<any> drain at all upon your code's performance. In fact, by itself
828ecf13 750it does nothing to affect your existing code. So you only pay for what
751you actually use.
bfe4d0fc 752
550d56db 753=head2 About Metaclass compatibility
754
1d68af04 755This module makes sure that all metaclasses created are both upwards
756and downwards compatible. The topic of metaclass compatibility is
757highly esoteric and is something only encountered when doing deep and
758involved metaclass hacking. There are two basic kinds of metaclass
759incompatibility; upwards and downwards.
550d56db 760
1d68af04 761Upwards metaclass compatibility means that the metaclass of a
762given class is either the same as (or a subclass of) all of the
550d56db 763class's ancestors.
764
1d68af04 765Downward metaclass compatibility means that the metaclasses of a
828ecf13 766given class's ancestors are all either the same as (or a subclass
550d56db 767of) that metaclass.
768
1d68af04 769Here is a diagram showing a set of two classes (C<A> and C<B>) and
770two metaclasses (C<Meta::A> and C<Meta::B>) which have correct
550d56db 771metaclass compatibility both upwards and downwards.
772
773 +---------+ +---------+
774 | Meta::A |<----| Meta::B | <....... (instance of )
1d68af04 775 +---------+ +---------+ <------- (inherits from)
550d56db 776 ^ ^
777 : :
778 +---------+ +---------+
779 | A |<----| B |
780 +---------+ +---------+
781
1d68af04 782As I said this is a highly esoteric topic and one you will only run
828ecf13 783into if you do a lot of subclassing of L<Class::MOP::Class>. If you
784are interested in why this is an issue see the paper I<Uniform and
785safe metaclass composition> linked to in the L<SEE ALSO> section of
786this document.
550d56db 787
aa448b16 788=head2 Using custom metaclasses
789
828ecf13 790Always use the L<metaclass> pragma when using a custom metaclass, this
5b60bf98 791will ensure the proper initialization order and not accidentally
792create an incorrect type of metaclass for you. This is a very rare
793problem, and one which can only occur if you are doing deep metaclass
aa448b16 794programming. So in other words, don't worry about it.
795
828ecf13 796Note that if you're using L<Moose> we encourage you to I<not> use
797L<metaclass> pragma, and instead use L<Moose::Util::MetaRole> to apply
798roles to a class's metaclasses. This topic is covered at length in
799various L<Moose::Cookbook> recipes.
800
94b19069 801=head1 PROTOCOLS
802
828ecf13 803The meta-object protocol is divided into 4 main sub-protocols:
94b19069 804
828ecf13 805=head2 The Class protocol
94b19069 806
1d68af04 807This provides a means of manipulating and introspecting a Perl 5
828ecf13 808class. It handles symbol table hacking for you, and provides a rich
809set of methods that go beyond simple package introspection.
94b19069 810
552e3d24 811See L<Class::MOP::Class> for more details.
812
828ecf13 813=head2 The Attribute protocol
94b19069 814
828ecf13 815This provides a consistent representation for an attribute of a Perl 5
816class. Since there are so many ways to create and handle attributes in
817Perl 5 OO, the Attribute protocol provide as much of a unified
818approach as possible. Of course, you are always free to extend this
819protocol by subclassing the appropriate classes.
94b19069 820
552e3d24 821See L<Class::MOP::Attribute> for more details.
822
828ecf13 823=head2 The Method protocol
94b19069 824
828ecf13 825This provides a means of manipulating and introspecting methods in the
826Perl 5 object system. As with attributes, there are many ways to
1d68af04 827approach this topic, so we try to keep it pretty basic, while still
94b19069 828making it possible to extend the system in many ways.
829
552e3d24 830See L<Class::MOP::Method> for more details.
94b19069 831
828ecf13 832=head2 The Instance protocol
127d39a7 833
828ecf13 834This provides a layer of abstraction for creating object instances.
835Since the other layers use this protocol, it is relatively easy to
836change the type of your instances from the default hash reference to
837some other type of reference. Several examples are provided in the
838F<examples/> directory included in this distribution.
127d39a7 839
840See L<Class::MOP::Instance> for more details.
841
be7677c7 842=head1 FUNCTIONS
843
828ecf13 844Note that this module does not export any constants or functions.
845
c1d5345a 846=head2 Constants
847
848=over 4
849
828ecf13 850=item I<Class::MOP::IS_RUNNING_ON_5_10>
c1d5345a 851
828ecf13 852We set this constant depending on what version perl we are on, this
853allows us to take advantage of new 5.10 features and stay backwards
5b60bf98 854compatible.
c1d5345a 855
828ecf13 856=item I<Class::MOP::HAVE_ISAREV>
9efe16ca 857
5b60bf98 858Whether or not the L<mro> pragma provides C<get_isarev>, a much faster
828ecf13 859way to get all the subclasses of a certain class.
9efe16ca 860
c1d5345a 861=back
862
448b6e55 863=head2 Utility functions
864
bd07fbdb 865Note that these are all called as B<functions, not methods>.
081a927b 866
448b6e55 867=over 4
868
828ecf13 869=item B<Class::MOP::load_class($class_name)>
448b6e55 870
828ecf13 871This will load the specified C<$class_name>. This function can be used
872in place of tricks like C<eval "use $module"> or using C<require>
873unconditionally.
448b6e55 874
828ecf13 875=item B<Class::MOP::is_class_loaded($class_name)>
448b6e55 876
15ab5451 877Returns a boolean indicating whether or not C<$class_name> has been
878loaded.
448b6e55 879
828ecf13 880This does a basic check of the symbol table to try and determine as
881best it can if the C<$class_name> is loaded, it is probably correct
882about 99% of the time, but it can be fooled into reporting false
883positives.
448b6e55 884
cdac22cc 885=item B<Class::MOP::get_code_info($code)>
886
887This function returns two values, the name of the package the C<$code>
888is from and the name of the C<$code> itself. This is used by several
5b60bf98 889elements of the MOP to determine where a given C<$code> reference is
cdac22cc 890from.
891
44ba77a3 892=item B<Class::MOP::class_of($instance_or_class_name)>
893
894This will return the metaclass of the given instance or class name.
895Even if the class lacks a metaclass, no metaclass will be initialized
896and C<undef> will be returned.
897
828ecf13 898=item B<Class::MOP::check_package_cache_flag($pkg)>
e0e4674a 899
bd07fbdb 900B<NOTE: DO NOT USE THIS FUNCTION, IT IS FOR INTERNAL USE ONLY!>
901
828ecf13 902This will return an integer that is managed by L<Class::MOP::Class> to
903determine if a module's symbol table has been altered.
127d39a7 904
828ecf13 905In Perl 5.10 or greater, this flag is package specific. However in
906versions prior to 5.10, this will use the C<PL_sub_generation>
907variable which is not package specific.
127d39a7 908
828ecf13 909=item B<Class::MOP::load_first_existing_class(@class_names)>
063ad0c5 910
911B<NOTE: DO NOT USE THIS FUNCTION, IT IS FOR INTERNAL USE ONLY!>
912
913Given a list of class names, this function will attempt to load each
914one in turn.
915
828ecf13 916If it finds a class it can load, it will return that class' name. If
917none of the classes can be loaded, it will throw an exception.
063ad0c5 918
448b6e55 919=back
920
921=head2 Metaclass cache functions
922
6c842677 923Class::MOP holds a cache of metaclasses. The following are functions
1d68af04 924(B<not methods>) which can be used to access that cache. It is not
6c842677 925recommended that you mess with these. Bad things could happen, but if
926you are brave and willing to risk it: go for it!
be7677c7 927
928=over 4
929
828ecf13 930=item B<Class::MOP::get_all_metaclasses>
be7677c7 931
6c842677 932This will return a hash of all the metaclass instances that have
828ecf13 933been cached by L<Class::MOP::Class>, keyed by the package name.
b9d9fc0b 934
828ecf13 935=item B<Class::MOP::get_all_metaclass_instances>
be7677c7 936
6c842677 937This will return a list of all the metaclass instances that have
828ecf13 938been cached by L<Class::MOP::Class>.
b9d9fc0b 939
828ecf13 940=item B<Class::MOP::get_all_metaclass_names>
be7677c7 941
6c842677 942This will return a list of all the metaclass names that have
828ecf13 943been cached by L<Class::MOP::Class>.
b9d9fc0b 944
828ecf13 945=item B<Class::MOP::get_metaclass_by_name($name)>
be7677c7 946
828ecf13 947This will return a cached L<Class::MOP::Class> instance, or nothing
6c842677 948if no metaclass exists with that C<$name>.
127d39a7 949
828ecf13 950=item B<Class::MOP::store_metaclass_by_name($name, $meta)>
be7677c7 951
127d39a7 952This will store a metaclass in the cache at the supplied C<$key>.
953
828ecf13 954=item B<Class::MOP::weaken_metaclass($name)>
be7677c7 955
6c842677 956In rare cases (e.g. anonymous metaclasses) it is desirable to
957store a weakened reference in the metaclass cache. This
958function will weaken the reference to the metaclass stored
959in C<$name>.
127d39a7 960
828ecf13 961=item B<Class::MOP::does_metaclass_exist($name)>
be7677c7 962
828ecf13 963This will return true of there exists a metaclass stored in the
6c842677 964C<$name> key, and return false otherwise.
127d39a7 965
828ecf13 966=item B<Class::MOP::remove_metaclass_by_name($name)>
be7677c7 967
6c842677 968This will remove the metaclass stored in the C<$name> key.
127d39a7 969
be7677c7 970=back
971
552e3d24 972=head1 SEE ALSO
8b978dd5 973
552e3d24 974=head2 Books
8b978dd5 975
1d68af04 976There are very few books out on Meta Object Protocols and Metaclasses
977because it is such an esoteric topic. The following books are really
978the only ones I have found. If you know of any more, B<I<please>>
a2e85e6c 979email me and let me know, I would love to hear about them.
980
8b978dd5 981=over 4
982
15ab5451 983=item I<The Art of the Meta Object Protocol>
8b978dd5 984
15ab5451 985=item I<Advances in Object-Oriented Metalevel Architecture and Reflection>
8b978dd5 986
15ab5451 987=item I<Putting MetaClasses to Work>
b51af7f9 988
15ab5451 989=item I<Smalltalk: The Language>
a2e85e6c 990
94b19069 991=back
992
550d56db 993=head2 Papers
994
995=over 4
996
15ab5451 997=item "Uniform and safe metaclass composition"
550d56db 998
1d68af04 999An excellent paper by the people who brought us the original Traits paper.
1000This paper is on how Traits can be used to do safe metaclass composition,
1001and offers an excellent introduction section which delves into the topic of
550d56db 1002metaclass compatibility.
1003
1004L<http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf>
1005
15ab5451 1006=item "Safe Metaclass Programming"
550d56db 1007
1d68af04 1008This paper seems to precede the above paper, and propose a mix-in based
1009approach as opposed to the Traits based approach. Both papers have similar
1010information on the metaclass compatibility problem space.
550d56db 1011
1012L<http://citeseer.ist.psu.edu/37617.html>
1013
1014=back
1015
552e3d24 1016=head2 Prior Art
8b978dd5 1017
1018=over 4
1019
7184ca14 1020=item The Perl 6 MetaModel work in the Pugs project
8b978dd5 1021
1022=over 4
1023
552e3d24 1024=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel>
8b978dd5 1025
552e3d24 1026=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-ObjectSpace>
8b978dd5 1027
1028=back
1029
94b19069 1030=back
1031
1d68af04 1032=head2 Articles
f8dfcfb7 1033
1034=over 4
1035
1d68af04 1036=item CPAN Module Review of Class::MOP
f8dfcfb7 1037
1038L<http://www.oreillynet.com/onlamp/blog/2006/06/cpan_module_review_classmop.html>
1039
1040=back
1041
a2e85e6c 1042=head1 SIMILAR MODULES
1043
1d68af04 1044As I have said above, this module is a class-builder-builder, so it is
1045not the same thing as modules like L<Class::Accessor> and
1046L<Class::MethodMaker>. That being said there are very few modules on CPAN
1047with similar goals to this module. The one I have found which is most
1048like this module is L<Class::Meta>, although it's philosophy and the MOP it
1049creates are very different from this modules.
94b19069 1050
a2e85e6c 1051=head1 BUGS
1052
1d68af04 1053All complex software has bugs lurking in it, and this module is no
a2e85e6c 1054exception. If you find a bug please either email me, or add the bug
1055to cpan-RT.
1056
1057=head1 ACKNOWLEDGEMENTS
1058
1059=over 4
1060
b9d9fc0b 1061=item Rob Kinyon
a2e85e6c 1062
1d68af04 1063Thanks to Rob for actually getting the development of this module kick-started.
a2e85e6c 1064
1065=back
1066
1a09d9cc 1067=head1 AUTHORS
94b19069 1068
a2e85e6c 1069Stevan Little E<lt>stevan@iinteractive.comE<gt>
552e3d24 1070
9c8cda90 1071B<with contributions from:>
1072
1073Brandon (blblack) Black
1074
4f116037 1075Florian (rafl) Ragwitz
1076
9c8cda90 1077Guillermo (groditi) Roditi
1078
9195ddff 1079Matt (mst) Trout
1080
9c8cda90 1081Rob (robkinyon) Kinyon
1082
1083Yuval (nothingmuch) Kogman
1a09d9cc 1084
f430cfa4 1085Scott (konobi) McWhirter
1086
94b19069 1087=head1 COPYRIGHT AND LICENSE
1088
070bb6c9 1089Copyright 2006-2009 by Infinity Interactive, Inc.
94b19069 1090
1091L<http://www.iinteractive.com>
1092
1093This library is free software; you can redistribute it and/or modify
1d68af04 1094it under the same terms as Perl itself.
94b19069 1095
1096=cut