* Moose
[gitmo/Moose.git] / lib / Moose.pm
index 673d6b6..9b8c5eb 100644 (file)
@@ -4,7 +4,7 @@ package Moose;
 use strict;
 use warnings;
 
-our $VERSION   = '0.19';
+our $VERSION   = '0.21';
 our $AUTHORITY = 'cpan:STEVAN';
 
 use Scalar::Util 'blessed', 'reftype';
@@ -92,8 +92,9 @@ use Moose::Util::TypeConstraints;
         has => sub {
             my $class = $CALLER;
             return subname 'Moose::has' => sub ($;%) {
-                my ($name, %options) = @_;              
-                $class->meta->_process_attribute($name, %options);
+                my ($name, %options) = @_;
+                my $attrs = (ref($name) eq 'ARRAY') ? $name : [($name)];
+                $class->meta->_process_attribute($_, %options) for @$attrs;
             };
         },
         before => sub {
@@ -121,6 +122,11 @@ use Moose::Util::TypeConstraints;
             };
         },
         super => sub {
+            {
+              our %SUPER_SLOT;
+              no strict 'refs';
+              $SUPER_SLOT{$CALLER} = \*{"${CALLER}::super"};
+            }
             return subname 'Moose::super' => sub {};
         },
         override => sub {
@@ -131,6 +137,11 @@ use Moose::Util::TypeConstraints;
             };
         },
         inner => sub {
+            {
+              our %INNER_SLOT;
+              no strict 'refs';
+              $INNER_SLOT{$CALLER} = \*{"${CALLER}::inner"};
+            }
             return subname 'Moose::inner' => sub {};
         },
         augment => sub {
@@ -200,7 +211,6 @@ use Moose::Util::TypeConstraints;
         my $class = caller();
         # loop through the exports ...
         foreach my $name (keys %exports) {
-            next if $name =~ /inner|super|self/;
             
             # if we find one ...
             if (defined &{$class . '::' . $name}) {
@@ -364,7 +374,7 @@ superclasses still properly inherit from L<Moose::Object>.
 This will apply a given set of C<@roles> to the local class. Role support 
 is currently under heavy development; see L<Moose::Role> for more details.
 
-=item B<has ($name, %options)>
+=item B<has $name =E<gt> %options>
 
 This will install an attribute of a given C<$name> into the current class. 
 The list of C<%options> are the same as those provided by 
@@ -424,6 +434,22 @@ If an attribute is marked as lazy it B<must> have a default supplied.
 This tells the accessor whether to automatically dereference the value returned. 
 This is only legal if your C<isa> option is either an C<ArrayRef> or C<HashRef>.
 
+=item I<metaclass =E<gt> $metaclass_name>
+
+This tells the class to use a custom attribute metaclass for this particular 
+attribute. Custom attribute metaclasses are useful for extending the capabilities 
+of the I<has> keyword, they are the simplest way to extend the MOP, but they are 
+still a fairly advanced topic and too much to cover here. I will try and write a 
+recipe on it soon.
+
+The default behavior here is to just load C<$metaclass_name>, however, we also 
+have a way to alias to a shorter name. This will first look to see if 
+B<Moose::Meta::Attribute::Custom::$metaclass_name> exists, if it does it will 
+then check to see if that has the method C<register_implemenetation> which 
+should return the actual name of the custom attribute metaclass. If there is 
+no C<register_implemenetation> method, it will just default to using 
+B<Moose::Meta::Attribute::Custom::$metaclass_name> as the metaclass name.
+
 =item I<trigger =E<gt> $code>
 
 The trigger option is a CODE reference which will be called after the value of 
@@ -442,7 +468,7 @@ B<NOTE:> This features is no longer experimental, but it still may have subtle
 bugs lurking in the deeper corners. So if you think you have found a bug, you 
 probably have, so please report it to me right away. 
 
-B<NOTE:> The class being delegated too does not need to be a Moose based class. 
+B<NOTE:> The class being delegated to does not need to be a Moose based class. 
 Which is why this feature is especially useful when wrapping non-Moose classes.
 
 All handles option formats share the following traits. 
@@ -475,7 +501,7 @@ for each one in the list.
 This is the second most common usage for handles. Instead of a list of 
 method names, you pass a HASH ref where the key is the method name you 
 want installed locally, and the value is the name of the original method 
-in the class being delegated too. 
+in the class being delegated to. 
 
 This can be very useful for recursive classes like trees, here is a 
 quick example (soon to be expanded into a Moose::Cookbook::Recipe):
@@ -509,7 +535,7 @@ in the parent slot.
 
 The regexp option works very similar to the ARRAY option, except that it builds 
 the list of methods for you. It starts by collecting all possible methods of the 
-class being delegated too, then filters that list using the regexp supplied here. 
+class being delegated to, then filters that list using the regexp supplied here. 
 
 B<NOTE:> An I<isa> option is required when using the regexp option format. This 
 is so that we can determine (at compile time) the method list from the class. 
@@ -522,14 +548,67 @@ only use it if you really know what you are doing as it involves manual metaclas
 twiddling.
 
 This takes a code reference, which should expect two arguments. The first is 
-the attribute meta-object this I<handles> is attached too. The second is the metaclass
-of the class being delegated too. It expects you to return a hash (not a HASH ref)
+the attribute meta-object this I<handles> is attached to. The second is the metaclass
+of the class being delegated to. It expects you to return a hash (not a HASH ref)
 of the methods you want mapped. 
 
 =back
 
 =back
 
+=item B<has +$name =E<gt> %options>
+
+This is variation on the normal attibute creator C<has>, which allows you to 
+clone and extend an attribute from a superclass. Here is a quick example:
+
+  package Foo;
+  use Moose;
+  
+  has 'message' => (
+      is      => 'rw', 
+      isa     => 'Str',
+      default => 'Hello, I am a Foo'
+  );
+  
+  package My::Foo;
+  use Moose;
+  
+  extends 'Foo';
+  
+  has '+message' => (default => 'Hello I am My::Foo');
+
+What is happening here is that B<My::Foo> is cloning the C<message> attribute 
+from it's parent class B<Foo>, retaining the is =E<gt> 'rw' and isa =E<gt> 'Str'
+characteristics, but changing the value in C<default>.
+
+This feature is restricted somewhat, so as to try and enfore at least I<some>
+sanity into it. You are only allowed to change the following attributes:
+
+=over 4
+
+=item I<default> 
+
+Change the default value of an attribute.
+
+=item I<coerce> 
+
+Change whether the attribute attempts to coerce a value passed to it.
+
+=item I<required> 
+
+Change if the attribute is required to have a value.
+
+=item I<documentation>
+
+Change the documentation string associated with the attribute.
+
+=item I<isa>
+
+You I<are> allowed to change the type, but if and B<only if> the new type is
+a subtype of the old type.  
+
+=back
+
 =item B<before $name|@names =E<gt> sub { ... }>
 
 =item B<after $name|@names =E<gt> sub { ... }>