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