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