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