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