handles => A::Role
[gitmo/Moose.git] / lib / Moose.pm
index e7c581e..a4e670b 100644 (file)
@@ -4,7 +4,7 @@ package Moose;
 use strict;
 use warnings;
 
-our $VERSION   = '0.19';
+our $VERSION   = '0.24';
 our $AUTHORITY = 'cpan:STEVAN';
 
 use Scalar::Util 'blessed', 'reftype';
@@ -14,7 +14,7 @@ use B            'svref_2object';
 
 use Sub::Exporter;
 
-use Class::MOP;
+use Class::MOP 0.39;
 
 use Moose::Meta::Class;
 use Moose::Meta::TypeConstraint;
@@ -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}) {
@@ -253,9 +263,7 @@ Moose - A complete modern object system for Perl 5
 =head1 SYNOPSIS
 
   package Point;
-  use strict;
-  use warnings;
-  use Moose;
+  use Moose; # automatically turns on strict and warnings
        
   has 'x' => (is => 'rw', isa => 'Int');
   has 'y' => (is => 'rw', isa => 'Int');
@@ -267,8 +275,6 @@ Moose - A complete modern object system for Perl 5
   }
   
   package Point3D;
-  use strict;
-  use warnings;  
   use Moose;
   
   extends 'Point';
@@ -300,8 +306,7 @@ programming.
 =head2 Is this for real? Or is this just an experiment?
 
 Moose is I<based> on the prototypes and experiments I did for the Perl 6
-meta-model; however Moose is B<NOT> an experiment/prototype, it is 
-for B<real>. 
+meta-model. However, Moose is B<NOT> an experiment/prototype; it is for B<real>. 
 
 =head2 Is this ready for use in production? 
 
@@ -319,7 +324,7 @@ or just stop by #moose and ask away.
 =head2 Is Moose just Perl 6 in Perl 5?
 
 No. While Moose is very much inspired by Perl 6, it is not itself Perl 6.
-Instead, it is an OO system for Perl 5. I built Moose because I was tired or
+Instead, it is an OO system for Perl 5. I built Moose because I was tired of
 writing the same old boring Perl 5 OO code, and drooling over Perl 6 OO. So
 instead of switching to Ruby, I wrote Moose :)
 
@@ -332,16 +337,16 @@ to. Here are a few items to note when building classes with Moose.
 Unless specified with C<extends>, any class which uses Moose will 
 inherit from L<Moose::Object>.
 
-Moose will also manage all attributes (including inherited ones) that 
-are defined with C<has>. And assuming that you call C<new>, which is 
-inherited from L<Moose::Object>, then this includes properly initializing 
-all instance slots, setting defaults where appropriate, and performing any 
-type constraint checking or coercion. 
+Moose will also manage all attributes (including inherited ones) that are
+defined with C<has>. And (assuming you call C<new>, which is inherited from
+L<Moose::Object>) this includes properly initializing all instance slots,
+setting defaults where appropriate, and performing any type constraint checking
+or coercion.
 
 =head1 EXPORTED FUNCTIONS
 
 Moose will export a number of functions into the class's namespace which 
-can then be used to set up the class. These functions all work directly 
+may then be used to set up the class. These functions all work directly 
 on the current class.
 
 =over 4
@@ -364,10 +369,10 @@ 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 
+The C<%options> are the same as those provided by 
 L<Class::MOP::Attribute>, in addition to the list below which are provided 
 by Moose (L<Moose::Meta::Attribute> to be more specific):
 
@@ -379,15 +384,16 @@ The I<is> option accepts either I<rw> (for read/write) or I<ro> (for read
 only). These will create either a read/write accessor or a read-only 
 accessor respectively, using the same name as the C<$name> of the attribute.
 
-If you need more control over how your accessors are named, you can use the 
-I<reader>, I<writer> and I<accessor> options inherited from L<Class::MOP::Attribute>.
+If you need more control over how your accessors are named, you can use the
+I<reader>, I<writer> and I<accessor> options inherited from
+L<Class::MOP::Attribute>.
 
 =item I<isa =E<gt> $type_name>
 
 The I<isa> option uses Moose's type constraint facilities to set up runtime 
 type checking for this attribute. Moose will perform the checks during class 
 construction, and within any accessors. The C<$type_name> argument must be a 
-string. The string can be either a class name or a type defined using 
+string. The string may be either a class name or a type defined using 
 Moose's type definition features.
 
 =item I<coerce =E<gt> (1|0)>
@@ -395,7 +401,7 @@ Moose's type definition features.
 This will attempt to use coercion with the supplied type constraint to change 
 the value passed into any accessors or constructors. You B<must> have supplied 
 a type constraint in order for this to work. See L<Moose::Cookbook::Recipe5>
-for an example usage.
+for an example.
 
 =item I<does =E<gt> $role_name>
 
@@ -405,7 +411,7 @@ is expected to have consumed.
 =item I<required =E<gt> (1|0)>
 
 This marks the attribute as being required. This means a value must be supplied 
-during class construction, and the attribute can never be set to C<undef> with 
+during class construction, and the attribute may never be set to C<undef> with 
 an accessor. 
 
 =item I<weak_ref =E<gt> (1|0)>
@@ -422,20 +428,188 @@ If an attribute is marked as lazy it B<must> have a default supplied.
 =item I<auto_deref =E<gt> (1|0)>
 
 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>.
+This is only legal if your C<isa> option is either 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 them 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, Moose
+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 fall back 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 
-the attribute is set. The CODE ref will be passed the instance itself, the 
+The I<trigger> option is a CODE reference which will be called after the value of
+the attribute is set. The CODE ref will be passed the instance itself, the
 updated value and the attribute meta-object (this is for more advanced fiddling
-and can typically be ignored in most cases). You B<cannot> have a trigger on
-a read-only attribute.
+and can typically be ignored). You B<cannot> have a trigger on a read-only
+attribute.
+
+=item I<handles =E<gt> ARRAY | HASH | REGEXP | ROLE | CODE>
+
+The I<handles> option provides Moose classes with automated delegation features. 
+This is a pretty complex and powerful option. It accepts many different option 
+formats, each with its own benefits and drawbacks. 
+
+B<NOTE:> This feature is no longer experimental, but it may still have subtle
+bugs lurking in the deeper corners. 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 to does not need to be a Moose based class,
+which is why this feature is especially useful when wrapping non-Moose classes.
+
+All I<handles> option formats share the following traits:
+
+You cannot override a locally defined method with a delegated method; an
+exception will be thrown if you try. That is to say, if you define C<foo> in
+your class, you cannot override it with a delegated C<foo>. This is almost never
+something you would want to do, and if it is, you should do it by hand and not
+use Moose.
+
+You cannot override any of the methods found in Moose::Object, or the C<BUILD>
+and C<DEMOLISH> methods. These will not throw an exception, but will silently
+move on to the next method in the list. My reasoning for this is that you would
+almost never want to do this, since it usually breaks your class. As with
+overriding locally defined methods, if you do want to do this, you should do it
+manually, not with Moose.
+
+Below is the documentation for each option format:
+
+=over 4
+
+=item C<ARRAY>
+
+This is the most common usage for I<handles>. You basically pass a list of 
+method names to be delegated, and Moose will install a delegation method 
+for each one.
+
+=item C<HASH>
+
+This is the second most common usage for I<handles>. Instead of a list of 
+method names, you pass a HASH ref where each key is the method name you 
+want installed locally, and its value is the name of the original method 
+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):
+
+  package Tree;
+  use Moose;
+  
+  has 'node' => (is => 'rw', isa => 'Any');
+  
+  has 'children' => (
+      is      => 'ro',
+      isa     => 'ArrayRef',
+      default => sub { [] }
+  );
+  
+  has 'parent' => (
+      is          => 'rw',
+      isa         => 'Tree',
+      is_weak_ref => 1,
+      handles     => {
+          parent_node => 'node',
+          siblings    => 'children', 
+      }
+  );
+
+In this example, the Tree package gets C<parent_node> and C<siblings> methods,
+which delegate to the C<node> and C<children> methods (respectively) of the Tree
+instance stored in the C<parent> slot. 
+
+=item C<REGEXP>
+
+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 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. 
+Without an I<isa> this is just not possible.
+
+=item C<ROLE>
+
+With the role option, you specify the name of a role whose "interface" then 
+becomes the list of methods to handle. The "interface" can be defined as; the 
+methods of the role and any required methods of the role. It should be noted 
+that this does B<not> include any method modifiers or generated attribute 
+methods (which is consistent with role composition).
+
+=item C<CODE>
+
+This is the option to use when you really want to do something funky. You should
+only use it if you really know what you are doing, as it involves manual
+metaclass twiddling.
+
+This takes a code reference, which should expect two arguments. The first is 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 its parent class B<Foo>, retaining the C<is =E<gt> 'rw'> and C<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>
 
-=item I<handles =E<gt> [ @handles ]>
+Change the documentation string associated with the attribute.
 
-There is experimental support for attribute delegation using the C<handles> 
-option. More docs to come later.
+=item I<isa>
+
+You I<are> allowed to change the type, B<if and only if> the new type is a
+subtype of the old type.
 
 =back
 
@@ -445,9 +619,10 @@ option. More docs to come later.
 
 =item B<around $name|@names =E<gt> sub { ... }>
 
-This three items are syntactic sugar for the before, after, and around method 
-modifier features that L<Class::MOP> provides. More information on these can 
-be found in the L<Class::MOP> documentation for now. 
+This three items are syntactic sugar for the before, after, and around method
+modifier features that L<Class::MOP> provides. More information on these may be
+found in the L<Class::MOP::Class documentation|Class::MOP::Class/"Method
+Modifiers"> for now.
 
 =item B<super>
 
@@ -482,17 +657,17 @@ all the time. This feature may change in the future, so you have been warned.
 
 =item B<blessed>
 
-This is the C<Scalar::Uti::blessed> function, it is exported here because I
+This is the C<Scalar::Util::blessed> function, it is exported here because I
 use it all the time. It is highly recommended that this is used instead of 
 C<ref> anywhere you need to test for an object's class name.
 
 =back
 
-=head1 UNEXPORTING FUNCTIONS
+=head1 UNIMPORTING FUNCTIONS
 
 =head2 B<unimport>
 
-Moose offers a way of removing the keywords it exports though the C<unimport>
+Moose offers a way to remove the keywords it exports, through the C<unimport>
 method. You simply have to say C<no Moose> at the bottom of your code for this
 to work. Here is an example:
 
@@ -509,50 +684,25 @@ to work. Here is an example:
     
     no Moose; # keywords are removed from the Person package    
 
-=head1 MISC.
-
-=head2 What does Moose stand for??
-
-Moose doesn't stand for one thing in particular, however, if you 
-want, here are a few of my favorites; feel free to contribute
-more :)
-
-=over 4
-
-=item Make Other Object Systems Envious
-
-=item Makes Object Orientation So Easy
-
-=item Makes Object Orientation Spiffy- Er  (sorry ingy)
-
-=item Most Other Object Systems Emasculate
-
-=item Moose Often Ovulate Sorta Early
-
-=item Moose Offers Often Super Extensions
-
-=item Meta Object Orientation Syntax Extensions
-
-=back
-
 =head1 CAVEATS
 
 =over 4
 
 =item *
 
-It should be noted that C<super> and C<inner> C<cannot> be used in the same 
-method. However, they can be combined together with the same class hierarchy;
-see F<t/014_override_augment_inner_super.t> for an example. 
+It should be noted that C<super> and C<inner> B<cannot> be used in the same
+method. However, they may be combined within the same class hierarchy; see
+F<t/014_override_augment_inner_super.t> for an example.
 
 The reason for this is that C<super> is only valid within a method 
 with the C<override> modifier, and C<inner> will never be valid within an 
 C<override> method. In fact, C<augment> will skip over any C<override> methods 
 when searching for its appropriate C<inner>.
 
-This might seem like a restriction, but I am of the opinion that keeping these 
-two features separate (but interoperable) actually makes them easy to use, since 
-their behavior is then easier to predict. Time will tell if I am right or not.
+This might seem like a restriction, but I am of the opinion that keeping these
+two features separate (yet interoperable) actually makes them easy to use, since
+their behavior is then easier to predict. Time will tell whether I am right or
+not (UPDATE: so far so good).
 
 =back
 
@@ -571,7 +721,7 @@ and it certainly wouldn't have this name ;P
 originally, I just ran with it.
 
 =item Thanks to mst & chansen and the whole #moose poose for all the 
-ideas/feature-requests/encouragement
+early ideas/feature-requests/encouragement/bug-finding.
 
 =item Thanks to David "Theory" Wheeler for meta-discussions and spelling fixes.
 
@@ -581,19 +731,31 @@ ideas/feature-requests/encouragement
 
 =over 4
 
+=item L<http://www.iinteractive.com/moose>
+
+This is the official web home of Moose, it contains links to our public SVN repo
+as well as links to a number of talks and articles on Moose and Moose related 
+technologies. 
+
 =item L<Class::MOP> documentation
 
 =item The #moose channel on irc.perl.org
 
 =item The Moose mailing list - moose@perl.org
 
-=item L<http://forum2.org/moose/>
+=item Moose stats on ohloh.net - L<http://www.ohloh.net/projects/5788>
+
+=back
+
+=head2 Papers 
+
+=over 4
 
 =item L<http://www.cs.utah.edu/plt/publications/oopsla04-gff.pdf>
 
 This paper (suggested by lbr on #moose) was what lead to the implementation 
-of the C<super>/C<overrride> and C<inner>/C<augment> features. If you really 
-want to understand this feature, I suggest you read this.
+of the C<super>/C<override> and C<inner>/C<augment> features. If you really 
+want to understand them, I suggest you read this.
 
 =back
 
@@ -607,9 +769,35 @@ to cpan-RT.
 
 Stevan Little E<lt>stevan@iinteractive.comE<gt>
 
-Christian Hansen E<lt>chansen@cpan.orgE<gt>
+B<with contributions from:>
+
+Aankhen
+
+Adam (Alias) Kennedy
+
+Anders (Debolaz) Nor Berle
+
+Christian (chansen) Hansen
+
+Eric (ewilhelm) Wilhelm
+
+Guillermo (groditi) Roditi
+
+Jess (castaway) Robinson
+
+Matt (mst) Trout
+
+Robert (phaylon) Sedlacek
+
+Robert (rlb3) Boone
+
+Scott (konobi) McWhirter
+
+Yuval (nothingmuch) Kogman
+
+Chris (perigrin) Prather
 
-Yuval Kogman E<lt>nothingmuch@woobling.orgE<gt>
+... and many other #moose folks
 
 =head1 COPYRIGHT AND LICENSE