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