no ref in the defaults
[gitmo/Class-MOP.git] / lib / Class / MOP.pm
index d55df90..3fd61ed 100644 (file)
@@ -13,7 +13,8 @@ use Class::MOP::Method;
 
 use Class::MOP::Class::Immutable;
 
-our $VERSION = '0.29_02';
+our $VERSION   = '0.33';
+our $AUTHORITY = 'cpan:STEVAN';
 
 ## ----------------------------------------------------------------------------
 ## Setting up our environment ...
@@ -39,9 +40,10 @@ our $VERSION = '0.29_02';
 # any subclass of Class::MOP::* will be able to 
 # inherit them using &construct_instance
 
-## Class::MOP::Class
+## --------------------------------------------------------
+## Class::MOP::Package
 
-Class::MOP::Class->meta->add_attribute(
+Class::MOP::Package->meta->add_attribute(
     Class::MOP::Attribute->new('$:package' => (
         reader   => {
             # NOTE: we need to do this in order 
@@ -53,6 +55,81 @@ Class::MOP::Class->meta->add_attribute(
     ))
 );
 
+Class::MOP::Package->meta->add_attribute(
+    Class::MOP::Attribute->new('%:namespace' => (
+        reader => {
+            'namespace' => sub { (shift)->{'%:namespace'} }
+        },
+        default => sub {
+            my ($class) = @_;
+            no strict 'refs';
+            return \%{$class->name . '::'};
+        },
+        # NOTE:
+        # protect this from silliness 
+        init_arg => '!............( DO NOT DO THIS )............!',
+    ))
+);
+
+# NOTE:
+# use the metaclass to construct the meta-package
+# which is a superclass of the metaclass itself :P
+Class::MOP::Package->meta->add_method('initialize' => sub {
+    my $class        = shift;
+    my $package_name = shift;
+    $class->meta->new_object(':package' => $package_name, @_);  
+});
+
+## --------------------------------------------------------
+## Class::MOP::Module
+
+# NOTE:
+# yeah this is kind of stretching things a bit, 
+# but truthfully the version should be an attribute
+# of the Module, the weirdness comes from having to 
+# stick to Perl 5 convention and store it in the 
+# $VERSION package variable. Basically if you just 
+# squint at it, it will look how you want it to look. 
+# Either as a package variable, or as a attribute of
+# the metaclass, isn't abstraction great :)
+
+Class::MOP::Module->meta->add_attribute(
+    Class::MOP::Attribute->new('$:version' => (
+        reader => {
+            'version' => sub {  
+                my $self = shift;
+                ${$self->get_package_symbol('$VERSION')};
+            }
+        },
+        # NOTE:
+        # protect this from silliness 
+        init_arg => '!............( DO NOT DO THIS )............!',
+    ))
+);
+
+# NOTE:
+# By following the same conventions as version here, 
+# we are opening up the possibility that people can 
+# use the $AUTHORITY in non-Class::MOP modules as 
+# well.  
+
+Class::MOP::Module->meta->add_attribute(
+    Class::MOP::Attribute->new('$:authority' => (
+        reader => {
+            'authority' => sub {  
+                my $self = shift;
+                ${$self->get_package_symbol('$AUTHORITY')};
+            }
+        },       
+        # NOTE:
+        # protect this from silliness 
+        init_arg => '!............( DO NOT DO THIS )............!',
+    ))
+);
+
+## --------------------------------------------------------
+## Class::MOP::Class
+
 Class::MOP::Class->meta->add_attribute(
     Class::MOP::Attribute->new('%:attributes' => (
         reader   => {
@@ -95,6 +172,13 @@ Class::MOP::Class->meta->add_attribute(
     ))
 );
 
+# NOTE:
+# we don't actually need to tie the knot with 
+# Class::MOP::Class here, it is actually handled 
+# within Class::MOP::Class itself in the 
+# construct_class_instance method. 
+
+## --------------------------------------------------------
 ## Class::MOP::Attribute
 
 Class::MOP::Attribute->meta->add_attribute(
@@ -148,6 +232,13 @@ Class::MOP::Attribute->meta->add_attribute(
 );
 
 Class::MOP::Attribute->meta->add_attribute(
+    Class::MOP::Attribute->new('clearer' => (
+        reader    => 'clearer',
+        predicate => 'has_clearer',
+    ))
+);
+
+Class::MOP::Attribute->meta->add_attribute(
     Class::MOP::Attribute->new('init_arg' => (
         reader    => 'init_arg',
         predicate => 'has_init_arg',
@@ -176,6 +267,11 @@ Class::MOP::Attribute->meta->add_method('new' => sub {
         || confess "You must provide a name for the attribute";
     $options{init_arg} = $name 
         if not exists $options{init_arg};
+        
+    (Class::MOP::Attribute::is_default_a_coderef(\%options))
+        || confess("References are not allowed as default values, you must ". 
+                   "wrap then in a CODE reference (ex: sub { [] } and not [])")
+            if exists $options{default} && ref $options{default};        
 
     # return the new object
     $class->meta->new_object(name => $name, %options);
@@ -186,6 +282,17 @@ Class::MOP::Attribute->meta->add_method('clone' => sub {
     $self->meta->clone_object($self, @_);  
 });
 
+## --------------------------------------------------------
+## Now close all the Class::MOP::* classes
+
+Class::MOP::Package  ->meta->make_immutable(inline_constructor => 0);
+Class::MOP::Module   ->meta->make_immutable(inline_constructor => 0);
+Class::MOP::Class    ->meta->make_immutable(inline_constructor => 0);
+Class::MOP::Attribute->meta->make_immutable(inline_constructor => 0);
+Class::MOP::Method   ->meta->make_immutable(inline_constructor => 0);
+Class::MOP::Instance ->meta->make_immutable(inline_constructor => 0);
+Class::MOP::Object   ->meta->make_immutable(inline_constructor => 0);
+
 1;
 
 __END__
@@ -467,10 +574,12 @@ Thanks to Rob for actually getting the development of this module kick-started.
 
 =back
 
-=head1 AUTHOR
+=head1 AUTHORS
 
 Stevan Little E<lt>stevan@iinteractive.comE<gt>
 
+Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
+
 =head1 COPYRIGHT AND LICENSE
 
 Copyright 2006 by Infinity Interactive, Inc.