misc crap;
[gitmo/Class-MOP.git] / lib / Class / MOP.pm
1
2 package Class::MOP;
3
4 use strict;
5 use warnings;
6
7 use Scalar::Util 'blessed';
8 use Carp         'confess';
9
10 use Class::MOP::Class;
11 use Class::MOP::Attribute;
12 use Class::MOP::Method;
13
14 our $VERSION = '0.01';
15
16 sub import {
17     shift;
18     return unless @_;
19     if ($_[0] eq ':universal') {
20         *UNIVERSAL::meta = sub { 
21             Class::MOP::Class->initialize(blessed($_[0]) || $_[0]) 
22         };
23     }
24 }
25
26 ## ----------------------------------------------------------------------------
27 ## Bootstrapping 
28 ## ----------------------------------------------------------------------------
29 ## The code below here is to bootstrap our MOP with itself. This is also 
30 ## sometimes called "tying the knot". By doing this, we make it much easier
31 ## to extend the MOP through subclassing and such since now you can use the
32 ## MOP itself to extend itself. 
33 ## 
34 ## Yes, I know, thats weird and insane, but it's a good thing, trust me :)
35 ## ---------------------------------------------------------------------------- 
36
37 # We need to add in the meta-attributes here so that 
38 # any subclass of Class::MOP::* will be able to 
39 # inherit them using &construct_instance
40
41 ## Class::MOP::Class
42
43 Class::MOP::Class->meta->add_attribute(
44     Class::MOP::Attribute->new('$:pkg' => (
45         init_arg => ':pkg'
46     ))
47 );
48
49 Class::MOP::Class->meta->add_attribute(
50     Class::MOP::Attribute->new('%:attrs' => (
51         init_arg => ':attrs',
52         default  => sub { {} }
53     ))
54 );
55
56 ## Class::MOP::Attribute
57
58 Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('name'));
59 Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('accessor'));
60 Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('reader'));
61 Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('writer'));
62 Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('predicate'));
63 Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('init_arg'));
64 Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('default'));
65
66 # NOTE: (meta-circularity)
67 # This should be one of the last things done
68 # it will "tie the knot" with Class::MOP::Attribute
69 # so that it uses the attributes meta-objects 
70 # to construct itself. 
71 Class::MOP::Attribute->meta->add_method('new' => sub {
72     my $class   = shift;
73     my $name    = shift;
74     my %options = @_;    
75         
76     (defined $name && $name)
77         || confess "You must provide a name for the attribute";
78     (!exists $options{reader} && !exists $options{writer})
79         || confess "You cannot declare an accessor and reader and/or writer functions"
80             if exists $options{accessor};
81             
82     bless $class->meta->construct_instance(name => $name, %options) => $class;
83 });
84
85 # NOTE: (meta-circularity)
86 # This is how we "tie the knot" for the class
87 # meta-objects. This is used to construct the
88 # Class::MOP::Class instances after all the 
89 # bootstrapping is complete.
90 Class::MOP::Class->meta->add_method('construct_class_instance' => sub {
91     my ($class, $package_name) = @_;
92     (defined $package_name && $package_name)
93         || confess "You must pass a package name";      
94     bless Class::MOP::Class->meta->construct_instance(':pkg' => $package_name) => blessed($class) || $class        
95 });
96
97 1;
98
99 __END__
100
101 =pod
102
103 =head1 NAME 
104
105 Class::MOP - A Meta Object Protocol for Perl 5
106
107 =head1 SYNOPSIS
108
109   use Class::MOP ':universal';
110   
111   package Foo;
112   
113   Foo->meta->add_method('foo' => sub { ... });
114
115 =head1 DESCRIPTON
116
117 This module is an attempt to create a meta object protocol for the 
118 Perl 5 object system. It makes no attempt to change the behavior or 
119 characteristics of the Perl 5 object system, only to create a 
120 protocol for its manipulation and introspection.
121
122 That said, it does attempt to create the tools for building a rich 
123 set of extensions to the Perl 5 object system. Every attempt has been 
124 made for these tools to keep to the spirit of the Perl 5 object 
125 system that we all know and love.
126
127 =head2 What is a Meta Object Protocol?
128
129 A meta object protocol is an API to an object system. 
130
131 To be more specific, it is a set of abstractions of the components of 
132 an object system (typically things like; classes, object, methods, 
133 object attributes, etc.). These abstractions can then be used to both 
134 inspect and manipulate the object system which they describe.
135
136 It can be said that there are two MOPs for any object system; the 
137 implicit MOP, and the explicit MOP. The implicit MOP handles things 
138 like method dispatch or inheritance, which happen automatically as 
139 part of how the object system works. The explicit MOP typically 
140 handles the introspection/reflection features of the object system. 
141 All object systems have implicit MOPs, without one, they would not 
142 work. Explict MOPs however as less common, and depending on the 
143 language can vary from restrictive (Reflection in Java or C#) to 
144 wide open (CLOS is a perfect example). 
145
146 =head2 Yet Another Class Builder!! Why?
147
148 This is B<not> a class builder so much as it is a I<class builder 
149 B<builder>>. My intent is that an end user does not use this module 
150 directly, but instead this module is used by module authors to 
151 build extensions and features onto the Perl 5 object system. 
152
153 =head2 Who is this module for?
154
155 This module is specifically for anyone who has ever created or 
156 wanted to create a module for the Class:: namespace. The tools which 
157 this module will provide will hopefully make it easier to do more 
158 complex things with Perl 5 classes by removing such barriers as 
159 the need to hack the symbol tables, or understand the fine details 
160 of method dispatch. 
161
162 =head2 What changes do I have to make to use this module?
163
164 This module was designed to be as unintrusive as possible. Many of 
165 it's features are accessible without B<any> change to your existsing 
166 code at all. It is meant to be a compliment to your existing code and 
167 not an intrusion on your code base. Unlike many other B<Class::> 
168 modules, this module does require you subclass it, or even that you 
169 C<use> it in within your module's package. 
170
171 The only features which requires additions to your code are the 
172 attribute handling and instance construction features, and these are
173 both optional features as well. The only reason for this is because 
174 Perl 5's object system does not actually have these features built 
175 in. More information about this feature can be found below.
176
177 =head2 A Note about Performance?
178
179 It is a common misconception that explict MOPs are performance drains. 
180 But this is not a universal truth at all, it is an side-effect of 
181 specific implementations. For instance, using Java reflection is much 
182 slower because the JVM cannot take advantage of any compiler 
183 optimizations, and the JVM has to deal with much more runtime type 
184 information as well. Reflection in C# is marginally better as it was 
185 designed into the language and runtime (the CLR). In contrast, CLOS 
186 (the Common Lisp Object System) was built to support an explicit MOP, 
187 and so performance is tuned for it. 
188
189 This library in particular does it's absolute best to avoid putting 
190 B<any> drain at all upon your code's performance. In fact, by itself 
191 it does nothing to affect your existing code. So you only pay for 
192 what you actually use.
193
194 =head1 PROTOCOLS
195
196 The protocol is divided into 3 main sub-protocols:
197
198 =over 4
199
200 =item The Class protocol
201
202 This provides a means of manipulating and introspecting a Perl 5 
203 class. It handles all of symbol table hacking for you, and provides 
204 a rich set of methods that go beyond simple package introspection.
205
206 See L<Class::MOP::Class> for more details.
207
208 =item The Attribute protocol
209
210 This provides a consistent represenation for an attribute of a 
211 Perl 5 class. Since there are so many ways to create and handle 
212 atttributes in Perl 5 OO, this attempts to provide as much of a 
213 unified approach as possible, while giving the freedom and 
214 flexibility to subclass for specialization.
215
216 See L<Class::MOP::Attribute> for more details.
217
218 =item The Method protocol
219
220 This provides a means of manipulating and introspecting methods in 
221 the Perl 5 object system. As with attributes, there are many ways to 
222 approach this topic, so we try to keep it pretty basic, while still 
223 making it possible to extend the system in many ways.
224
225 See L<Class::MOP::Method> for more details.
226
227 =back
228
229 head1 BUGS
230
231 All complex software has bugs lurking in it, and this module is no 
232 exception. If you find a bug please either email me, or add the bug
233 to cpan-RT.
234
235 =head1 SEE ALSO
236
237 =head2 Books
238
239 =over 4
240
241 =item "The Art of the Meta Object Protocol"
242
243 =item "Advances in Object-Oriented Metalevel Architecture and Reflection"
244
245 =item "Putting MetaClasses to Work"
246
247 =back
248
249 =head2 Prior Art
250
251 =over 4
252
253 =item The Perl 6 MetaModel work in the Pugs project
254
255 =over 4
256
257 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel>
258
259 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-ObjectSpace>
260
261 =back
262
263 =back
264
265 =head1 AUTHOR
266
267 Stevan Little E<gt>stevan@iinteractive.comE<lt>
268
269 Rob Kinyon E<gt>rob@iinteractive.comE<lt>
270
271 =head1 COPYRIGHT AND LICENSE
272
273 Copyright 2006 by Infinity Interactive, Inc.
274
275 L<http://www.iinteractive.com>
276
277 This library is free software; you can redistribute it and/or modify
278 it under the same terms as Perl itself. 
279
280 =cut