preping for the 0.01 release
[gitmo/Class-MOP.git] / lib / Class / MOP.pm
index ce1b6e6..a401ee5 100644 (file)
@@ -5,14 +5,89 @@ use strict;
 use warnings;
 
 use Scalar::Util 'blessed';
+use Carp         'confess';
+
+use Class::MOP::Class;
+use Class::MOP::Attribute;
+use Class::MOP::Method;
 
 our $VERSION = '0.01';
 
-# my %METAS;
-# sub UNIVERSAL::meta { 
-#     my $class = blessed($_[0]) || $_[0];
-#     $METAS{$class} ||= Class::MOP::Class->initialize($class) 
-# }
+sub import {
+    shift;
+    return unless @_;
+    if ($_[0] eq ':universal') {
+        *UNIVERSAL::meta = sub { 
+            Class::MOP::Class->initialize(blessed($_[0]) || $_[0]) 
+        };
+    }
+    else {
+        my $pkg = caller();
+        no strict 'refs';
+        *{$pkg . '::' . $_[0]} = sub { 
+            Class::MOP::Class->initialize(blessed($_[0]) || $_[0]) 
+        };        
+    }
+}
+
+## ----------------------------------------------------------------------------
+## Bootstrapping 
+## ----------------------------------------------------------------------------
+## The code below here is to bootstrap our MOP with itself. This is also 
+## sometimes called "tying the knot". By doing this, we make it much easier
+## to extend the MOP through subclassing and such since now you can use the
+## MOP itself to extend itself. 
+## 
+## Yes, I know, thats weird and insane, but it's a good thing, trust me :)
+## ---------------------------------------------------------------------------- 
+
+# We need to add in the meta-attributes here so that 
+# any subclass of Class::MOP::* will be able to 
+# inherit them using &construct_instance
+
+## Class::MOP::Class
+
+Class::MOP::Class->meta->add_attribute(
+    Class::MOP::Attribute->new('$:pkg' => (
+        init_arg => ':pkg'
+    ))
+);
+
+Class::MOP::Class->meta->add_attribute(
+    Class::MOP::Attribute->new('%:attrs' => (
+        init_arg => ':attrs',
+        default  => sub { {} }
+    ))
+);
+
+## Class::MOP::Attribute
+
+Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('name'));
+Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('accessor'));
+Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('reader'));
+Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('writer'));
+Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('predicate'));
+Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('init_arg'));
+Class::MOP::Attribute->meta->add_attribute(Class::MOP::Attribute->new('default'));
+
+# NOTE: (meta-circularity)
+# This should be one of the last things done
+# it will "tie the knot" with Class::MOP::Attribute
+# so that it uses the attributes meta-objects 
+# to construct itself. 
+Class::MOP::Attribute->meta->add_method('new' => sub {
+    my $class   = shift;
+    my $name    = shift;
+    my %options = @_;    
+        
+    (defined $name && $name)
+        || confess "You must provide a name for the attribute";
+    (!exists $options{reader} && !exists $options{writer})
+        || confess "You cannot declare an accessor and reader and/or writer functions"
+            if exists $options{accessor};
+            
+    bless $class->meta->construct_instance(name => $name, %options) => $class;
+});
 
 1;
 
@@ -26,7 +101,8 @@ Class::MOP - A Meta Object Protocol for Perl 5
 
 =head1 SYNOPSIS
 
-  # ... coming soon
+  # ... This will come later, for now see
+  # the other SYNOPSIS for more information
 
 =head1 DESCRIPTON
 
@@ -77,16 +153,18 @@ of method dispatch.
 
 =head2 What changes do I have to make to use this module?
 
-This module was designed to be as unintrusive as possible. So many of 
+This module was designed to be as unintrusive as possible. Many of 
 it's features are accessible without B<any> change to your existsing 
 code at all. It is meant to be a compliment to your existing code and 
-not an intrusion on your code base.
+not an intrusion on your code base. Unlike many other B<Class::> 
+modules, this module B<does not> require you subclass it, or even that 
+you C<use> it in within your module's package. 
 
-The only feature which requires additions to your code are the 
-attribute handling and instance construction features. The only reason 
-for this is because Perl 5's object system does not actually have 
-these features built in. More information about this feature can be 
-found below.
+The only features which requires additions to your code are the 
+attribute handling and instance construction features, and these are
+both completely optional features. The only reason for this is because 
+Perl 5's object system does not actually have these features built 
+in. More information about this feature can be found below.
 
 =head2 A Note about Performance?
 
@@ -101,9 +179,9 @@ designed into the language and runtime (the CLR). In contrast, CLOS
 and so performance is tuned for it. 
 
 This library in particular does it's absolute best to avoid putting 
-B<any> drain at all upon your code's performance, while still trying 
-to make sure it is fast as well (although only as a secondary 
-concern).
+B<any> drain at all upon your code's performance. In fact, by itself 
+it does nothing to affect your existing code. So you only pay for 
+what you actually use.
 
 =head1 PROTOCOLS
 
@@ -144,19 +222,28 @@ See L<Class::MOP::Method> for more details.
 
 =head2 Books
 
+There are very few books out on Meta Object Protocols and Metaclasses 
+because it is such an esoteric topic. The following books are really 
+the only ones I have found. If you know of any more, B<I<please>> 
+email me and let me know, I would love to hear about them.
+
 =over 4
 
 =item "The Art of the Meta Object Protocol"
 
 =item "Advances in Object-Oriented Metalevel Architecture and Reflection"
 
+=item "Putting MetaClasses to Work"
+
+=item "Smalltalk: The Language"
+
 =back
 
 =head2 Prior Art
 
 =over 4
 
-=item The Perl 6 MetaModel work
+=item The Perl 6 MetaModel work in the Pugs project
 
 =over 4
 
@@ -168,11 +255,56 @@ See L<Class::MOP::Method> for more details.
 
 =back
 
-=head1 AUTHOR
+=head1 SIMILAR MODULES
+
+As I have said above, this module is a class-builder-builder, so it is 
+not the same thing as modules like L<Class::Accessor> and 
+L<Class::MethodMaker>. That being said there are very few modules on CPAN 
+with similar goals to this module. The one I have found which is most 
+like this module is L<Class::Meta>, although it's philosophy is very 
+different from this module. 
+
+To start with, it provides wrappers around common Perl data types, and even 
+extends those types with more specific subtypes. This module does not 
+go into that area at all. 
+
+L<Class::Meta> also seems to create it's own custom meta-object protocol, 
+which is both more restrictive and more featureful than the vanilla 
+Perl 5 one. This module attempts to model the existing Perl 5 MOP as it is.
+
+It's introspection capabilities also seem to be heavily rooted in this 
+custom MOP, so that you can only introspect classes which are already 
+created with L<Class::Meta>. This module does not make such restictions.
+
+Now, all this said, L<Class::Meta> is much more featureful than B<Class::MOP> 
+would ever try to be. But B<Class::MOP> has some features which L<Class::Meta>
+could not easily implement. It would be very possible to completely re-implement 
+L<Class::Meta> using B<Class::MOP> and bring some of these features to 
+L<Class::Meta> though. 
+
+But in the end, this module's admitedly ambitious goals have no direct equal 
+on CPAN since surely no one has been crazy enough to try something as silly 
+as this ;) until now.
 
-Stevan Little E<gt>stevan@iinteractive.comE<lt>
+=head1 BUGS
+
+All complex software has bugs lurking in it, and this module is no 
+exception. If you find a bug please either email me, or add the bug
+to cpan-RT.
+
+=head1 ACKNOWLEDGEMENTS
+
+=over 4
+
+=item Rob Kinyon E<lt>rob@iinteractive.comE<gt>
+
+Thanks to Rob for actually getting the development of this module kick-started. 
+
+=back
+
+=head1 AUTHOR
 
-Rob Kinyon E<gt>rob@iinteractive.comE<lt>
+Stevan Little E<lt>stevan@iinteractive.comE<gt>
 
 =head1 COPYRIGHT AND LICENSE