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