no-more-blessed-subs
[gitmo/Class-MOP.git] / lib / Class / MOP.pm
1
2 package Class::MOP;
3
4 use strict;
5 use warnings;
6
7 use Carp         'confess';
8 use Scalar::Util 'weaken';
9
10 use Class::MOP::Class;
11 use Class::MOP::Attribute;
12 use Class::MOP::Method;
13
14 use Class::MOP::Class::Immutable;
15
16 our $VERSION   = '0.34';
17 our $AUTHORITY = 'cpan:STEVAN';
18
19 {
20     # Metaclasses are singletons, so we cache them here.
21     # there is no need to worry about destruction though
22     # because they should die only when the program dies.
23     # After all, do package definitions even get reaped?
24     my %METAS;  
25     
26     # means of accessing all the metaclasses that have 
27     # been initialized thus far (for mugwumps obj browser)
28     sub get_all_metaclasses         {        %METAS         }            
29     sub get_all_metaclass_instances { values %METAS         } 
30     sub get_all_metaclass_names     { keys   %METAS         }     
31     sub get_metaclass_by_name       { $METAS{$_[0]}         }
32     sub store_metaclass_by_name     { $METAS{$_[0]} = $_[1] }  
33     sub weaken_metaclass            { weaken($METAS{$_[0]}) }            
34     sub does_metaclass_exist        { exists $METAS{$_[0]} && defined $METAS{$_[0]} }
35     sub remove_metaclass_by_name    { $METAS{$_[0]} = undef }     
36     
37     # NOTE:
38     # We only cache metaclasses, meaning instances of 
39     # Class::MOP::Class. We do not cache instance of 
40     # Class::MOP::Package or Class::MOP::Module. Mostly
41     # because I don't yet see a good reason to do so.        
42 }
43
44 ## ----------------------------------------------------------------------------
45 ## Setting up our environment ...
46 ## ----------------------------------------------------------------------------
47 ## Class::MOP needs to have a few things in the global perl environment so 
48 ## that it can operate effectively. Those things are done here.
49 ## ----------------------------------------------------------------------------
50
51 # ... nothing yet actually ;)
52
53 ## ----------------------------------------------------------------------------
54 ## Bootstrapping 
55 ## ----------------------------------------------------------------------------
56 ## The code below here is to bootstrap our MOP with itself. This is also 
57 ## sometimes called "tying the knot". By doing this, we make it much easier
58 ## to extend the MOP through subclassing and such since now you can use the
59 ## MOP itself to extend itself. 
60 ## 
61 ## Yes, I know, thats weird and insane, but it's a good thing, trust me :)
62 ## ---------------------------------------------------------------------------- 
63
64 # We need to add in the meta-attributes here so that 
65 # any subclass of Class::MOP::* will be able to 
66 # inherit them using &construct_instance
67
68 ## --------------------------------------------------------
69 ## Class::MOP::Package
70
71 Class::MOP::Package->meta->add_attribute(
72     Class::MOP::Attribute->new('$:package' => (
73         reader   => {
74             # NOTE: we need to do this in order 
75             # for the instance meta-object to 
76             # not fall into meta-circular death
77             'name' => sub { (shift)->{'$:package'} }
78         },
79         init_arg => ':package',
80     ))
81 );
82
83 Class::MOP::Package->meta->add_attribute(
84     Class::MOP::Attribute->new('%:namespace' => (
85         reader => {
86             # NOTE:
87             # because of issues with the Perl API 
88             # to the typeglob in some versions, we 
89             # need to just always grab a new 
90             # reference to the hash here. Ideally 
91             # we could just store a ref and it would
92             # Just Work, but oh well :\
93             'namespace' => sub { 
94                 no strict 'refs';
95                 \%{$_[0]->name . '::'} 
96             }
97         },
98         # NOTE:
99         # protect this from silliness 
100         init_arg => '!............( DO NOT DO THIS )............!',
101         default  => sub { \undef }
102     ))
103 );
104
105 # NOTE:
106 # use the metaclass to construct the meta-package
107 # which is a superclass of the metaclass itself :P
108 Class::MOP::Package->meta->add_method('initialize' => sub {
109     my $class        = shift;
110     my $package_name = shift;
111     $class->meta->new_object(':package' => $package_name, @_);  
112 });
113
114 ## --------------------------------------------------------
115 ## Class::MOP::Module
116
117 # NOTE:
118 # yeah this is kind of stretching things a bit, 
119 # but truthfully the version should be an attribute
120 # of the Module, the weirdness comes from having to 
121 # stick to Perl 5 convention and store it in the 
122 # $VERSION package variable. Basically if you just 
123 # squint at it, it will look how you want it to look. 
124 # Either as a package variable, or as a attribute of
125 # the metaclass, isn't abstraction great :)
126
127 Class::MOP::Module->meta->add_attribute(
128     Class::MOP::Attribute->new('$:version' => (
129         reader => {
130             'version' => sub {  
131                 my $self = shift;
132                 ${$self->get_package_symbol('$VERSION')};
133             }
134         },
135         # NOTE:
136         # protect this from silliness 
137         init_arg => '!............( DO NOT DO THIS )............!',
138         default  => sub { \undef }
139     ))
140 );
141
142 # NOTE:
143 # By following the same conventions as version here, 
144 # we are opening up the possibility that people can 
145 # use the $AUTHORITY in non-Class::MOP modules as 
146 # well.  
147
148 Class::MOP::Module->meta->add_attribute(
149     Class::MOP::Attribute->new('$:authority' => (
150         reader => {
151             'authority' => sub {  
152                 my $self = shift;
153                 ${$self->get_package_symbol('$AUTHORITY')};
154             }
155         },       
156         # NOTE:
157         # protect this from silliness 
158         init_arg => '!............( DO NOT DO THIS )............!',
159         default  => sub { \undef }
160     ))
161 );
162
163 ## --------------------------------------------------------
164 ## Class::MOP::Class
165
166 Class::MOP::Class->meta->add_attribute(
167     Class::MOP::Attribute->new('%:attributes' => (
168         reader   => {
169             # NOTE: we need to do this in order 
170             # for the instance meta-object to 
171             # not fall into meta-circular death            
172             'get_attribute_map' => sub { (shift)->{'%:attributes'} }
173         },
174         init_arg => ':attributes',
175         default  => sub { {} }
176     ))
177 );
178
179 Class::MOP::Class->meta->add_attribute(
180     Class::MOP::Attribute->new('%:methods' => (
181         #reader => 'get_method_map',
182         #reader   => {          
183         #    # NOTE:
184         #    # as with the $VERSION and $AUTHORITY above
185         #    # sometimes we don't/can't store directly 
186         #    # inside the instance, so we need the accessor
187         #    # to just DWIM
188         #    'get_method_map' => sub {
189         #        my $self = shift;
190         #        # FIXME:
191         #        # there is a faster/better way 
192         #        # to do this, I am sure :)    
193         #        return +{ 
194         #            map {
195         #                $_ => $self->method_metaclass->wrap($self->get_package_symbol('&' . $_)) 
196         #            } grep { 
197         #                $self->has_package_symbol('&' . $_) 
198         #            } $self->list_all_package_symbols
199         #        };            
200         #    }
201         #},
202         #init_arg => '!............( DO NOT DO THIS )............!',
203         #default  => sub { \undef }
204         default => sub { {} }
205     ))
206 );
207
208 Class::MOP::Class->meta->add_attribute(
209     Class::MOP::Attribute->new('$:attribute_metaclass' => (
210         reader   => 'attribute_metaclass',
211         init_arg => ':attribute_metaclass',
212         default  => 'Class::MOP::Attribute',
213     ))
214 );
215
216 Class::MOP::Class->meta->add_attribute(
217     Class::MOP::Attribute->new('$:method_metaclass' => (
218         reader   => 'method_metaclass',
219         init_arg => ':method_metaclass',
220         default  => 'Class::MOP::Method',        
221     ))
222 );
223
224 Class::MOP::Class->meta->add_attribute(
225     Class::MOP::Attribute->new('$:instance_metaclass' => (
226         reader   => {
227             # NOTE: we need to do this in order 
228             # for the instance meta-object to 
229             # not fall into meta-circular death            
230             'instance_metaclass' => sub { (shift)->{'$:instance_metaclass'} }
231         },
232         init_arg => ':instance_metaclass',
233         default  => 'Class::MOP::Instance',        
234     ))
235 );
236
237 # NOTE:
238 # we don't actually need to tie the knot with 
239 # Class::MOP::Class here, it is actually handled 
240 # within Class::MOP::Class itself in the 
241 # construct_class_instance method. 
242
243 ## --------------------------------------------------------
244 ## Class::MOP::Attribute
245
246 Class::MOP::Attribute->meta->add_attribute(
247     Class::MOP::Attribute->new('name' => (
248         reader => {
249             # NOTE: we need to do this in order 
250             # for the instance meta-object to 
251             # not fall into meta-circular death            
252             'name' => sub { (shift)->{name} }
253         }
254     ))
255 );
256
257 Class::MOP::Attribute->meta->add_attribute(
258     Class::MOP::Attribute->new('associated_class' => (
259         reader => {
260             # NOTE: we need to do this in order 
261             # for the instance meta-object to 
262             # not fall into meta-circular death            
263             'associated_class' => sub { (shift)->{associated_class} }
264         }
265     ))
266 );
267
268 Class::MOP::Attribute->meta->add_attribute(
269     Class::MOP::Attribute->new('accessor' => (
270         reader    => 'accessor',
271         predicate => 'has_accessor',
272     ))
273 );
274
275 Class::MOP::Attribute->meta->add_attribute(
276     Class::MOP::Attribute->new('reader' => (
277         reader    => 'reader',
278         predicate => 'has_reader',
279     ))
280 );
281
282 Class::MOP::Attribute->meta->add_attribute(
283     Class::MOP::Attribute->new('writer' => (
284         reader    => 'writer',
285         predicate => 'has_writer',
286     ))
287 );
288
289 Class::MOP::Attribute->meta->add_attribute(
290     Class::MOP::Attribute->new('predicate' => (
291         reader    => 'predicate',
292         predicate => 'has_predicate',
293     ))
294 );
295
296 Class::MOP::Attribute->meta->add_attribute(
297     Class::MOP::Attribute->new('clearer' => (
298         reader    => 'clearer',
299         predicate => 'has_clearer',
300     ))
301 );
302
303 Class::MOP::Attribute->meta->add_attribute(
304     Class::MOP::Attribute->new('init_arg' => (
305         reader    => 'init_arg',
306         predicate => 'has_init_arg',
307     ))
308 );
309
310 Class::MOP::Attribute->meta->add_attribute(
311     Class::MOP::Attribute->new('default' => (
312         # default has a custom 'reader' method ...
313         predicate => 'has_default',
314     ))
315 );
316
317
318 # NOTE: (meta-circularity)
319 # This should be one of the last things done
320 # it will "tie the knot" with Class::MOP::Attribute
321 # so that it uses the attributes meta-objects 
322 # to construct itself. 
323 Class::MOP::Attribute->meta->add_method('new' => sub {
324     my $class   = shift;
325     my $name    = shift;
326     my %options = @_;    
327         
328     (defined $name && $name)
329         || confess "You must provide a name for the attribute";
330     $options{init_arg} = $name 
331         if not exists $options{init_arg};
332         
333     (Class::MOP::Attribute::is_default_a_coderef(\%options))
334         || confess("References are not allowed as default values, you must ". 
335                    "wrap then in a CODE reference (ex: sub { [] } and not [])")
336             if exists $options{default} && ref $options{default};        
337
338     # return the new object
339     $class->meta->new_object(name => $name, %options);
340 });
341
342 Class::MOP::Attribute->meta->add_method('clone' => sub {
343     my $self  = shift;
344     $self->meta->clone_object($self, @_);  
345 });
346
347 ## --------------------------------------------------------
348 ## Now close all the Class::MOP::* classes
349
350 Class::MOP::Package  ->meta->make_immutable(inline_constructor => 0);
351 Class::MOP::Module   ->meta->make_immutable(inline_constructor => 0);
352 Class::MOP::Class    ->meta->make_immutable(inline_constructor => 0);
353 Class::MOP::Attribute->meta->make_immutable(inline_constructor => 0);
354 Class::MOP::Method   ->meta->make_immutable(inline_constructor => 0);
355 Class::MOP::Instance ->meta->make_immutable(inline_constructor => 0);
356 Class::MOP::Object   ->meta->make_immutable(inline_constructor => 0);
357
358 1;
359
360 __END__
361
362 =pod
363
364 =head1 NAME 
365
366 Class::MOP - A Meta Object Protocol for Perl 5
367
368 =head1 SYNOPSIS
369
370   # ... This will come later, for now see
371   # the other SYNOPSIS for more information
372
373 =head1 DESCRIPTON
374
375 This module is an attempt to create a meta object protocol for the 
376 Perl 5 object system. It makes no attempt to change the behavior or 
377 characteristics of the Perl 5 object system, only to create a 
378 protocol for its manipulation and introspection.
379
380 That said, it does attempt to create the tools for building a rich 
381 set of extensions to the Perl 5 object system. Every attempt has been 
382 made for these tools to keep to the spirit of the Perl 5 object 
383 system that we all know and love.
384
385 This documentation is admittedly sparse on details, as time permits 
386 I will try to improve them. For now, I suggest looking at the items 
387 listed in the L<SEE ALSO> section for more information. In particular 
388 the book "The Art of the Meta Object Protocol" was very influential 
389 in the development of this system.
390
391 =head2 What is a Meta Object Protocol?
392
393 A meta object protocol is an API to an object system. 
394
395 To be more specific, it is a set of abstractions of the components of 
396 an object system (typically things like; classes, object, methods, 
397 object attributes, etc.). These abstractions can then be used to both 
398 inspect and manipulate the object system which they describe.
399
400 It can be said that there are two MOPs for any object system; the 
401 implicit MOP, and the explicit MOP. The implicit MOP handles things 
402 like method dispatch or inheritance, which happen automatically as 
403 part of how the object system works. The explicit MOP typically 
404 handles the introspection/reflection features of the object system. 
405 All object systems have implicit MOPs, without one, they would not 
406 work. Explict MOPs however as less common, and depending on the 
407 language can vary from restrictive (Reflection in Java or C#) to 
408 wide open (CLOS is a perfect example). 
409
410 =head2 Yet Another Class Builder!! Why?
411
412 This is B<not> a class builder so much as it is a I<class builder 
413 B<builder>>. My intent is that an end user does not use this module 
414 directly, but instead this module is used by module authors to 
415 build extensions and features onto the Perl 5 object system. 
416
417 =head2 Who is this module for?
418
419 This module is specifically for anyone who has ever created or 
420 wanted to create a module for the Class:: namespace. The tools which 
421 this module will provide will hopefully make it easier to do more 
422 complex things with Perl 5 classes by removing such barriers as 
423 the need to hack the symbol tables, or understand the fine details 
424 of method dispatch. 
425
426 =head2 What changes do I have to make to use this module?
427
428 This module was designed to be as unintrusive as possible. Many of 
429 its features are accessible without B<any> change to your existsing 
430 code at all. It is meant to be a compliment to your existing code and 
431 not an intrusion on your code base. Unlike many other B<Class::> 
432 modules, this module B<does not> require you subclass it, or even that 
433 you C<use> it in within your module's package. 
434
435 The only features which requires additions to your code are the 
436 attribute handling and instance construction features, and these are
437 both completely optional features. The only reason for this is because 
438 Perl 5's object system does not actually have these features built 
439 in. More information about this feature can be found below.
440
441 =head2 A Note about Performance?
442
443 It is a common misconception that explict MOPs are performance drains. 
444 But this is not a universal truth at all, it is an side-effect of 
445 specific implementations. For instance, using Java reflection is much 
446 slower because the JVM cannot take advantage of any compiler 
447 optimizations, and the JVM has to deal with much more runtime type 
448 information as well. Reflection in C# is marginally better as it was 
449 designed into the language and runtime (the CLR). In contrast, CLOS 
450 (the Common Lisp Object System) was built to support an explicit MOP, 
451 and so performance is tuned for it. 
452
453 This library in particular does it's absolute best to avoid putting 
454 B<any> drain at all upon your code's performance. In fact, by itself 
455 it does nothing to affect your existing code. So you only pay for 
456 what you actually use.
457
458 =head2 About Metaclass compatibility
459
460 This module makes sure that all metaclasses created are both upwards 
461 and downwards compatible. The topic of metaclass compatibility is 
462 highly esoteric and is something only encountered when doing deep and 
463 involved metaclass hacking. There are two basic kinds of metaclass 
464 incompatibility; upwards and downwards. 
465
466 Upwards metaclass compatibility means that the metaclass of a 
467 given class is either the same as (or a subclass of) all of the 
468 class's ancestors.
469
470 Downward metaclass compatibility means that the metaclasses of a 
471 given class's anscestors are all either the same as (or a subclass 
472 of) that metaclass.
473
474 Here is a diagram showing a set of two classes (C<A> and C<B>) and 
475 two metaclasses (C<Meta::A> and C<Meta::B>) which have correct  
476 metaclass compatibility both upwards and downwards.
477
478     +---------+     +---------+
479     | Meta::A |<----| Meta::B |      <....... (instance of  )
480     +---------+     +---------+      <------- (inherits from)  
481          ^               ^
482          :               :
483     +---------+     +---------+
484     |    A    |<----|    B    |
485     +---------+     +---------+
486
487 As I said this is a highly esoteric topic and one you will only run 
488 into if you do a lot of subclassing of B<Class::MOP::Class>. If you 
489 are interested in why this is an issue see the paper 
490 I<Uniform and safe metaclass composition> linked to in the 
491 L<SEE ALSO> section of this document.
492
493 =head2 Using custom metaclasses
494
495 Always use the metaclass pragma when using a custom metaclass, this 
496 will ensure the proper initialization order and not accidentely 
497 create an incorrect type of metaclass for you. This is a very rare 
498 problem, and one which can only occur if you are doing deep metaclass 
499 programming. So in other words, don't worry about it.
500
501 =head1 PROTOCOLS
502
503 The protocol is divided into 3 main sub-protocols:
504
505 =over 4
506
507 =item The Class protocol
508
509 This provides a means of manipulating and introspecting a Perl 5 
510 class. It handles all of symbol table hacking for you, and provides 
511 a rich set of methods that go beyond simple package introspection.
512
513 See L<Class::MOP::Class> for more details.
514
515 =item The Attribute protocol
516
517 This provides a consistent represenation for an attribute of a 
518 Perl 5 class. Since there are so many ways to create and handle 
519 atttributes in Perl 5 OO, this attempts to provide as much of a 
520 unified approach as possible, while giving the freedom and 
521 flexibility to subclass for specialization.
522
523 See L<Class::MOP::Attribute> for more details.
524
525 =item The Method protocol
526
527 This provides a means of manipulating and introspecting methods in 
528 the Perl 5 object system. As with attributes, there are many ways to 
529 approach this topic, so we try to keep it pretty basic, while still 
530 making it possible to extend the system in many ways.
531
532 See L<Class::MOP::Method> for more details.
533
534 =back
535
536 =head1 FUNCTIONS
537
538 Class::MOP holds a cache of metaclasses, the following are functions 
539 (B<not methods>) which can be used to access that cache. It is not 
540 recommended that you mess with this, bad things could happen. But if 
541 you are brave and willing to risk it, go for it.
542
543 =over 4
544
545 =item B<get_all_metaclasses>
546
547 This will return an hash of all the metaclass instances that have 
548 been cached by B<Class::MOP::Class> keyed by the package name. 
549
550 =item B<get_all_metaclass_instances>
551
552 This will return an array of all the metaclass instances that have 
553 been cached by B<Class::MOP::Class>.
554
555 =item B<get_all_metaclass_names>
556
557 This will return an array of all the metaclass names that have 
558 been cached by B<Class::MOP::Class>.
559
560 =item B<get_metaclass_by_name ($name)>
561
562 =item B<store_metaclass_by_name ($name, $meta)>
563
564 =item B<weaken_metaclass ($name)>
565
566 =item B<does_metaclass_exist ($name)>
567
568 =item B<remove_metaclass_by_name ($name)>
569
570 =back
571
572 =head1 SEE ALSO
573
574 =head2 Books
575
576 There are very few books out on Meta Object Protocols and Metaclasses 
577 because it is such an esoteric topic. The following books are really 
578 the only ones I have found. If you know of any more, B<I<please>> 
579 email me and let me know, I would love to hear about them.
580
581 =over 4
582
583 =item "The Art of the Meta Object Protocol"
584
585 =item "Advances in Object-Oriented Metalevel Architecture and Reflection"
586
587 =item "Putting MetaClasses to Work"
588
589 =item "Smalltalk: The Language"
590
591 =back
592
593 =head2 Papers
594
595 =over 4
596
597 =item Uniform and safe metaclass composition
598
599 An excellent paper by the people who brought us the original Traits paper. 
600 This paper is on how Traits can be used to do safe metaclass composition, 
601 and offers an excellent introduction section which delves into the topic of 
602 metaclass compatibility.
603
604 L<http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf>
605
606 =item Safe Metaclass Programming
607
608 This paper seems to precede the above paper, and propose a mix-in based 
609 approach as opposed to the Traits based approach. Both papers have similar 
610 information on the metaclass compatibility problem space. 
611
612 L<http://citeseer.ist.psu.edu/37617.html>
613
614 =back
615
616 =head2 Prior Art
617
618 =over 4
619
620 =item The Perl 6 MetaModel work in the Pugs project
621
622 =over 4
623
624 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel>
625
626 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-ObjectSpace>
627
628 =back
629
630 =back
631
632 =head1 SIMILAR MODULES
633
634 As I have said above, this module is a class-builder-builder, so it is 
635 not the same thing as modules like L<Class::Accessor> and 
636 L<Class::MethodMaker>. That being said there are very few modules on CPAN 
637 with similar goals to this module. The one I have found which is most 
638 like this module is L<Class::Meta>, although it's philosophy and the MOP it 
639 creates are very different from this modules. 
640
641 =head1 BUGS
642
643 All complex software has bugs lurking in it, and this module is no 
644 exception. If you find a bug please either email me, or add the bug
645 to cpan-RT.
646
647 =head1 CODE COVERAGE
648
649 I use L<Devel::Cover> to test the code coverage of my tests, below is the 
650 L<Devel::Cover> report on this module's test suite.
651
652  ---------------------------- ------ ------ ------ ------ ------ ------ ------
653  File                           stmt   bran   cond    sub    pod   time  total
654  ---------------------------- ------ ------ ------ ------ ------ ------ ------
655  Class/MOP.pm                   78.0   87.5   55.6   71.4  100.0   12.4   76.8
656  Class/MOP/Attribute.pm         83.4   75.6   86.7   94.4  100.0    8.9   85.2
657  Class/MOP/Class.pm             96.9   75.8   43.2   98.0  100.0   55.3   83.6
658  Class/MOP/Class/Immutable.pm   88.5   53.8    n/a   95.8  100.0    1.1   84.7
659  Class/MOP/Instance.pm          87.9   75.0   33.3   89.7  100.0   10.1   89.1
660  Class/MOP/Method.pm            97.6   60.0   57.9   76.9  100.0    1.5   82.8
661  Class/MOP/Module.pm            87.5    n/a   11.1   83.3  100.0    0.3   66.7
662  Class/MOP/Object.pm           100.0    n/a   33.3  100.0  100.0    0.1   89.5
663  Class/MOP/Package.pm           95.1   69.0   33.3  100.0  100.0    9.9   85.5
664  metaclass.pm                  100.0  100.0   83.3  100.0    n/a    0.5   97.7
665  ---------------------------- ------ ------ ------ ------ ------ ------ ------
666  Total                          91.5   72.1   48.8   90.7  100.0  100.0   84.2
667  ---------------------------- ------ ------ ------ ------ ------ ------ ------
668
669 =head1 ACKNOWLEDGEMENTS
670
671 =over 4
672
673 =item Rob Kinyon
674
675 Thanks to Rob for actually getting the development of this module kick-started. 
676
677 =back
678
679 =head1 AUTHORS
680
681 Stevan Little E<lt>stevan@iinteractive.comE<gt>
682
683 Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
684
685 =head1 COPYRIGHT AND LICENSE
686
687 Copyright 2006 by Infinity Interactive, Inc.
688
689 L<http://www.iinteractive.com>
690
691 This library is free software; you can redistribute it and/or modify
692 it under the same terms as Perl itself. 
693
694 =cut