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