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