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