Clarify public-ness of Class::MOP functions
[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
1e7b526a 847Note that these are all called as B<functions, not methods>. They are
848"public" in the sense that they're documented for use by other
849Class::MOP and Moose modules, but they're not really intended for use
850in end-user code.
081a927b 851
448b6e55 852=over 4
853
854=item B<load_class ($class_name)>
855
1d68af04 856This will load a given C<$class_name> and if it does not have an
448b6e55 857already initialized metaclass, then it will intialize one for it.
127d39a7 858This function can be used in place of tricks like
859C<eval "use $module"> or using C<require>.
448b6e55 860
861=item B<is_class_loaded ($class_name)>
862
1d68af04 863This will return a boolean depending on if the C<$class_name> has
864been loaded.
448b6e55 865
1d68af04 866NOTE: This does a basic check of the symbol table to try and
448b6e55 867determine as best it can if the C<$class_name> is loaded, it
1d68af04 868is probably correct about 99% of the time.
448b6e55 869
b1f5f41d 870=item B<check_package_cache_flag ($pkg)>
e0e4674a 871
127d39a7 872This will return an integer that is managed by C<Class::MOP::Class>
873to determine if a module's symbol table has been altered.
874
875In Perl 5.10 or greater, this flag is package specific. However in
876versions prior to 5.10, this will use the C<PL_sub_generation> variable
877which is not package specific.
878
e0e4674a 879=item B<get_code_info ($code)>
880
127d39a7 881This function returns two values, the name of the package the C<$code>
882is from and the name of the C<$code> itself. This is used by several
883elements of the MOP to detemine where a given C<$code> reference is from.
884
4c105333 885=item B<subname ($name, $code)>
886
887B<NOTE: DO NOT USE THIS FUNCTION, IT IS FOR INTERNAL USE ONLY!>
888
889If possible, we will load the L<Sub::Name> module and this will function
890as C<Sub::Name::subname> does, otherwise it will just return the C<$code>
891argument.
892
6f49cf3f 893=item B<in_global_destruction>
894
895If L<Devel::GlobalDestruction> is available, this returns true under global
896destruction.
897
898Otherwise it's a constant returning false.
899
448b6e55 900=back
901
902=head2 Metaclass cache functions
903
1d68af04 904Class::MOP holds a cache of metaclasses, the following are functions
905(B<not methods>) which can be used to access that cache. It is not
906recommended that you mess with this, bad things could happen. But if
be7677c7 907you are brave and willing to risk it, go for it.
908
909=over 4
910
911=item B<get_all_metaclasses>
912
1d68af04 913This will return an hash of all the metaclass instances that have
914been cached by B<Class::MOP::Class> keyed by the package name.
b9d9fc0b 915
be7677c7 916=item B<get_all_metaclass_instances>
917
1d68af04 918This will return an array of all the metaclass instances that have
b9d9fc0b 919been cached by B<Class::MOP::Class>.
920
be7677c7 921=item B<get_all_metaclass_names>
922
1d68af04 923This will return an array of all the metaclass names that have
b9d9fc0b 924been cached by B<Class::MOP::Class>.
925
be7677c7 926=item B<get_metaclass_by_name ($name)>
927
127d39a7 928This will return a cached B<Class::MOP::Class> instance of nothing
929if no metaclass exist by that C<$name>.
930
be7677c7 931=item B<store_metaclass_by_name ($name, $meta)>
932
127d39a7 933This will store a metaclass in the cache at the supplied C<$key>.
934
be7677c7 935=item B<weaken_metaclass ($name)>
936
127d39a7 937In rare cases it is desireable to store a weakened reference in
938the metaclass cache. This function will weaken the reference to
939the metaclass stored in C<$name>.
940
be7677c7 941=item B<does_metaclass_exist ($name)>
942
127d39a7 943This will return true of there exists a metaclass stored in the
944C<$name> key and return false otherwise.
945
be7677c7 946=item B<remove_metaclass_by_name ($name)>
947
127d39a7 948This will remove a the metaclass stored in the C<$name> key.
949
be7677c7 950=back
951
552e3d24 952=head1 SEE ALSO
8b978dd5 953
552e3d24 954=head2 Books
8b978dd5 955
1d68af04 956There are very few books out on Meta Object Protocols and Metaclasses
957because it is such an esoteric topic. The following books are really
958the only ones I have found. If you know of any more, B<I<please>>
a2e85e6c 959email me and let me know, I would love to hear about them.
960
8b978dd5 961=over 4
962
552e3d24 963=item "The Art of the Meta Object Protocol"
8b978dd5 964
552e3d24 965=item "Advances in Object-Oriented Metalevel Architecture and Reflection"
8b978dd5 966
b51af7f9 967=item "Putting MetaClasses to Work"
968
a2e85e6c 969=item "Smalltalk: The Language"
970
94b19069 971=back
972
550d56db 973=head2 Papers
974
975=over 4
976
977=item Uniform and safe metaclass composition
978
1d68af04 979An excellent paper by the people who brought us the original Traits paper.
980This paper is on how Traits can be used to do safe metaclass composition,
981and offers an excellent introduction section which delves into the topic of
550d56db 982metaclass compatibility.
983
984L<http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf>
985
986=item Safe Metaclass Programming
987
1d68af04 988This paper seems to precede the above paper, and propose a mix-in based
989approach as opposed to the Traits based approach. Both papers have similar
990information on the metaclass compatibility problem space.
550d56db 991
992L<http://citeseer.ist.psu.edu/37617.html>
993
994=back
995
552e3d24 996=head2 Prior Art
8b978dd5 997
998=over 4
999
7184ca14 1000=item The Perl 6 MetaModel work in the Pugs project
8b978dd5 1001
1002=over 4
1003
552e3d24 1004=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel>
8b978dd5 1005
552e3d24 1006=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-ObjectSpace>
8b978dd5 1007
1008=back
1009
94b19069 1010=back
1011
1d68af04 1012=head2 Articles
f8dfcfb7 1013
1014=over 4
1015
1d68af04 1016=item CPAN Module Review of Class::MOP
f8dfcfb7 1017
1018L<http://www.oreillynet.com/onlamp/blog/2006/06/cpan_module_review_classmop.html>
1019
1020=back
1021
a2e85e6c 1022=head1 SIMILAR MODULES
1023
1d68af04 1024As I have said above, this module is a class-builder-builder, so it is
1025not the same thing as modules like L<Class::Accessor> and
1026L<Class::MethodMaker>. That being said there are very few modules on CPAN
1027with similar goals to this module. The one I have found which is most
1028like this module is L<Class::Meta>, although it's philosophy and the MOP it
1029creates are very different from this modules.
94b19069 1030
a2e85e6c 1031=head1 BUGS
1032
1d68af04 1033All complex software has bugs lurking in it, and this module is no
a2e85e6c 1034exception. If you find a bug please either email me, or add the bug
1035to cpan-RT.
1036
1037=head1 ACKNOWLEDGEMENTS
1038
1039=over 4
1040
b9d9fc0b 1041=item Rob Kinyon
a2e85e6c 1042
1d68af04 1043Thanks to Rob for actually getting the development of this module kick-started.
a2e85e6c 1044
1045=back
1046
1a09d9cc 1047=head1 AUTHORS
94b19069 1048
a2e85e6c 1049Stevan Little E<lt>stevan@iinteractive.comE<gt>
552e3d24 1050
9c8cda90 1051B<with contributions from:>
1052
1053Brandon (blblack) Black
1054
1055Guillermo (groditi) Roditi
1056
9195ddff 1057Matt (mst) Trout
1058
9c8cda90 1059Rob (robkinyon) Kinyon
1060
1061Yuval (nothingmuch) Kogman
1a09d9cc 1062
f430cfa4 1063Scott (konobi) McWhirter
1064
94b19069 1065=head1 COPYRIGHT AND LICENSE
1066
69e3ab0a 1067Copyright 2006-2008 by Infinity Interactive, Inc.
94b19069 1068
1069L<http://www.iinteractive.com>
1070
1071This library is free software; you can redistribute it and/or modify
1d68af04 1072it under the same terms as Perl itself.
94b19069 1073
1074=cut