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