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