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