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