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