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