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