many-many-docs
Stevan Little [Tue, 21 Mar 2006 19:15:33 +0000 (19:15 +0000)]
Changes
lib/Moose.pm
lib/Moose/Meta/Attribute.pm
lib/Moose/Meta/Class.pm
lib/Moose/Meta/TypeCoercion.pm
lib/Moose/Meta/TypeConstraint.pm
lib/Moose/Object.pm
lib/Moose/Util/TypeConstraints.pm
t/003_basic.t
t/010_basic_class_setup.t

diff --git a/Changes b/Changes
index fc8b0ca..10976df 100644 (file)
--- a/Changes
+++ b/Changes
@@ -4,18 +4,14 @@ Revision history for Perl extension Moose
     * Moose
       - many more tests, fixing some bugs and  
         edge cases
-        
       - &extends now loads the base module with
         UNIVERSAL::require 
         - added UNIVERSAL::require to the 
           dependencies list
-
-      # API CHANGES #
-      
+      ** API CHANGES **
       - each new Moose class will also create 
         and register a subtype of Object which 
         correspond to the new Moose class.      
-      
       - the 'isa' option in &has now only 
         accepts strings, and will DWIM in 
         almost all cases
@@ -25,13 +21,15 @@ Revision history for Perl extension Moose
         - added tests for this
         - added support for this in attributes 
           and instance construction
-          
-      # API CHANGES #          
-          
+      ** API CHANGES **
       - type construction no longer creates a 
         function, it registers the type instead.
         - added several functions to get the 
           registered types 
+
+    * Moose::Object
+      - BUILDALL and DEMOLISHALL were broken 
+        because of a mis-named hash key, Whoops :)
     
     * Moose::Meta::Attribute
       - adding support for coercion in the
@@ -39,12 +37,12 @@ Revision history for Perl extension Moose
         
     * Moose::Meta::Class
       - adding support for coercion in the
-        instance construction        
-    
-    * Moose::Object
-    
-      - BUILDALL and DEMOLISHALL were broken 
-        because of a mis-named hash key, Whoops :)
+        instance construction  
+
+    * Moose::Meta::TypeConstraint
+    * Moose::Meta::TypeCoercion
+         - type constraints and coercions are now 
+           full fledges meta-objects
 
 0.01 Wed. March 15, 2006
     - Moooooooooooooooooose!!!
\ No newline at end of file
index 0a8424e..7f9d9a1 100644 (file)
@@ -205,6 +205,93 @@ more :)
 
 =back
 
+=head1 BUILDING CLASSES WITH MOOSE
+
+Moose makes every attempt to provide as much convience during class 
+construction/definition, but still stay out of your way if you want 
+it to. Here are some of the features Moose provides:
+
+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 approprtiate 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 
+on the current class.
+
+=over 4
+
+=item B<meta>
+
+This is a method which provides access to the current class's metaclass.
+
+=item B<extends (@superclasses)>
+
+This function will set the superclass(es) for the current class.
+
+This approach is recommended instead of C<use base>, because C<use base> 
+actually C<push>es onto the class's C<@ISA>, whereas C<extends> will 
+replace it. This is important to ensure that classes which do not have 
+superclasses properly inherit from L<Moose::Object>.
+
+=item B<has ($name, %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 both 
+L<Class::MOP::Attribute> and L<Moose::Meta::Attribute>, in addition to a 
+few convience ones provided by Moose which are listed below:
+
+=over 4
+
+=item I<is => 'rw'|'ro'>
+
+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<Moose::Meta::Attribute>.
+
+=item I<isa => $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 
+Moose's type defintion features.
+
+=back
+
+=item B<before $name|@names => sub { ... }>
+
+=item B<after $name|@names => sub { ... }>
+
+=item B<around $name|@names => 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. 
+
+=item B<confess>
+
+This is the C<Carp::confess> function, and exported here beause I use it 
+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 beause 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 ACKNOWLEDGEMENTS
 
 =over 4
@@ -228,6 +315,10 @@ ideas/feature-requests/encouragement
 
 =over 4
 
+=item L<Class::MOP> documentation
+
+=item The #moose channel on irc.perl.org
+
 =item L<http://forum2.org/moose/>
 
 =back
index 260796a..e7a40bc 100644 (file)
@@ -11,16 +11,13 @@ our $VERSION = '0.02';
 
 use base 'Class::MOP::Attribute';
 
-__PACKAGE__->meta->add_attribute('coerce'          => (reader => 'coerce'));
-__PACKAGE__->meta->add_attribute('weak_ref'        => (reader => 'weak_ref'));
+__PACKAGE__->meta->add_attribute('coerce'   => (reader => 'should_coerce'));
+__PACKAGE__->meta->add_attribute('weak_ref' => (reader => 'is_weak_ref'  ));
 __PACKAGE__->meta->add_attribute('type_constraint' => (
     reader    => 'type_constraint',
     predicate => 'has_type_constraint',
 ));
 
-sub should_coerce { (shift)->coerce()   ? 1 : 0 }
-sub is_weak_ref   { (shift)->weak_ref() ? 1 : 0 }
-
 __PACKAGE__->meta->add_before_method_modifier('new' => sub {
        my (undef, undef, %options) = @_;
        if (exists $options{coerce} && $options{coerce}) {
@@ -144,17 +141,26 @@ __END__
 
 =head1 NAME
 
-Moose::Meta::Attribute - The Moose attribute metaobject
-
-=head1 SYNOPSIS
+Moose::Meta::Attribute - The Moose attribute metaclass
 
 =head1 DESCRIPTION
 
 This is a subclass of L<Class::MOP::Attribute> with Moose specific 
-extensions.
+extensions. 
+
+For the most part, the only time you will ever encounter an 
+instance of this class is if you are doing some serious deep 
+introspection. To really understand this class, you need to refer 
+to the L<Class::MOP::Attribute> documentation.
 
 =head1 METHODS
 
+=head2 Overridden methods
+
+These methods override methods in L<Class::MOP::Attribute> and add 
+Moose specific features. You can safely assume though that they 
+will behave just as L<Class::MOP::Attribute> does.
+
 =over 4
 
 =item B<new>
@@ -165,20 +171,31 @@ extensions.
 
 =back
 
+=head2 Additional Moose features
+
+Moose attributes support type-contstraint checking, weak reference 
+creation and type coercion.  
+
 =over 4
 
 =item B<has_type_constraint>
 
+Returns true if this meta-attribute has a type constraint.
+
 =item B<type_constraint>
 
-=item B<is_weak_ref>
+A read-only accessor for this meta-attribute's type constraint. For 
+more information on what you can do with this, see the documentation 
+for L<Moose::Meta::TypeConstraint>.
 
-=item B<weak_ref>
+=item B<is_weak_ref>
 
-=item B<coerce>
+Returns true of this meta-attribute produces a weak reference.
 
 =item B<should_coerce>
 
+Returns true of this meta-attribute should perform type coercion.
+
 =back
 
 =head1 BUGS
index 76f42f3..a6fa937 100644 (file)
@@ -4,7 +4,8 @@ package Moose::Meta::Class;
 use strict;
 use warnings;
 
-use Carp 'confess';
+use Carp         'confess';
+use Scalar::Util 'weaken';
 
 our $VERSION = '0.02';
 
@@ -31,6 +32,9 @@ sub construct_instance {
             }
                }
         $instance->{$attr->name} = $val;
+        if (defined $val && $attr->is_weak_ref) {
+            weaken($instance->{$attr->name});
+        }
     }
     return $instance;
 }
@@ -45,20 +49,28 @@ __END__
 
 Moose::Meta::Class - The Moose metaclass
 
-=head1 SYNOPSIS
-
 =head1 DESCRIPTION
 
 This is a subclass of L<Class::MOP::Class> with Moose specific 
 extensions.
 
+For the most part, the only time you will ever encounter an 
+instance of this class is if you are doing some serious deep 
+introspection. To really understand this class, you need to refer 
+to the L<Class::MOP::Class> documentation.
+
 =head1 METHODS
 
 =over 4
 
 =item B<construct_instance>
 
-=item B<mixed_in>
+This provides some Moose specific extensions to this method, you 
+almost never call this method directly unless you really know what 
+you are doing. 
+
+This method makes sure to handle the moose weak-ref, type-constraint
+and type coercion features. 
 
 =back
 
index 2120734..1aaec3a 100644 (file)
@@ -70,12 +70,19 @@ __END__
 
 =head1 NAME
 
-Moose::Meta::TypeCoercion - The Moose Type Coercion metaobject
-
-=head1 SYNOPSIS
+Moose::Meta::TypeCoercion - The Moose Type Coercion metaclass
 
 =head1 DESCRIPTION
 
+For the most part, the only time you will ever encounter an 
+instance of this class is if you are doing some serious deep 
+introspection. This API should not be considered final, but 
+it is B<highly unlikely> that this will matter to a regular 
+Moose user.
+
+If you wish to use features at this depth, please come to the 
+#moose IRC channel on irc.perl.org and we can talk :)
+
 =head1 METHODS
 
 =over 4
@@ -84,10 +91,10 @@ Moose::Meta::TypeCoercion - The Moose Type Coercion metaobject
 
 =item B<new>
 
-=item B<coerce>
-
 =item B<compile_type_coercion>
 
+=item B<coerce>
+
 =item B<type_coercion_map>
 
 =item B<type_constraint>
index 4c1205c..518e448 100644 (file)
@@ -65,12 +65,19 @@ __END__
 
 =head1 NAME
 
-Moose::Meta::TypeConstraint - The Moose Type Constraint metaobject
-
-=head1 SYNOPSIS
+Moose::Meta::TypeConstraint - The Moose Type Constraint metaclass
 
 =head1 DESCRIPTION
 
+For the most part, the only time you will ever encounter an 
+instance of this class is if you are doing some serious deep 
+introspection. This API should not be considered final, but 
+it is B<highly unlikely> that this will matter to a regular 
+Moose user.
+
+If you wish to use features at this depth, please come to the 
+#moose IRC channel on irc.perl.org and we can talk :)
+
 =head1 METHODS
 
 =over 4
@@ -79,20 +86,20 @@ Moose::Meta::TypeConstraint - The Moose Type Constraint metaobject
 
 =item B<new>
 
+=item B<compile_type_constraint>
+
+=item B<check>
+
 =item B<name>
 
 =item B<parent>
 
-=item B<check>
-
 =item B<constraint>
 
 =item B<has_coercion>
 
 =item B<coercion>
 
-=item B<compile_type_constraint>
-
 =back
 
 =head1 BUGS
index 2117e0e..fca7419 100644 (file)
@@ -18,7 +18,7 @@ sub new {
 
 sub BUILDALL {
        my ($self, %params) = @_;
-       foreach my $method ($self->meta->find_all_methods_by_name('BUILD')) {
+       foreach my $method (reverse $self->meta->find_all_methods_by_name('BUILD')) {
                $method->{code}->($self, %params);
        }
 }
@@ -42,16 +42,25 @@ __END__
 
 Moose::Object - The base object for Moose
 
-=head1 SYNOPSIS 
-
 =head1 DESCRIPTION
 
+This serves as the base object for all Moose classes. Every 
+effort will be made to ensure that all classes which C<use Moose> 
+will inherit from this class. It provides a default constructor 
+and destructor, which run all the BUILD and DEMOLISH methods in 
+the class tree.
+
+You don't actually I<need> to inherit from this in order to 
+use Moose though. It is just here to make life easier.
+
 =head1 METHODS
 
 =over 4
 
 =item B<meta>
 
+This will return the metaclass associated with the given class.
+
 =item B<new>
 
 This will create a new instance and call C<BUILDALL>.
@@ -64,8 +73,6 @@ This will call every C<BUILD> method in the inheritance hierarchy.
 
 This will call every C<DEMOLISH> method in the inheritance hierarchy.
 
-=item B<NEXT>
-
 =back
 
 =head1 BUGS
index b70c870..2179e45 100644 (file)
@@ -138,7 +138,16 @@ This module provides Moose with the ability to create type contraints
 to be are used in both attribute definitions and for method argument 
 validation. 
 
-This is B<NOT> a type system for Perl 5.
+=head2 Important Caveat
+
+This is B<NOT> a type system for Perl 5. These are type constraints, 
+and they are not used by Moose unless you tell it to. No type 
+inference is performed, expression are not typed, etc. etc. etc. 
+
+This is simply a means of creating small constraint functions which 
+can be used to simply your own type-checking code.
+
+=head2 Default Type Constraints
 
 This module also provides a simple hierarchy for Perl 5 types, this 
 could probably use some work, but it works for me at the moment.
@@ -155,7 +164,7 @@ could probably use some work, but it works for me at the moment.
           RegexpRef
           Object       
 
-Suggestions for improvement are welcome.       
+Suggestions for improvement are welcome.
     
 =head1 FUNCTIONS
 
@@ -165,59 +174,72 @@ Suggestions for improvement are welcome.
 
 =item B<find_type_constraint ($type_name)>
 
-=item B<_create_type_constraint ($type_name, $type_constraint)>
-
-=item B<_install_type_coercions>
+This function can be used to locate a specific type constraint 
+meta-object. What you do with it from there is up to you :)
 
 =item B<export_type_contstraints_as_functions>
 
+This will export all the current type constraints as functions 
+into the caller's namespace. Right now, this is mostly used for 
+testing, but it might prove useful to others.
+
 =back
 
 =head2 Type Constraint Constructors
 
-=over 4
+The following functions are used to create type constraints. 
+They will then register the type constraints in a global store 
+where Moose can get to them if it needs to. 
 
-=item B<type>
+See the L<SYNOPOSIS> for an example of how to use these.
 
-=item B<subtype>
+=over 4
 
-=item B<as>
+=item B<type ($name, $where_clause)>
 
-=item B<where>
+This creates a base type, which has no parent. 
 
-=item B<coerce>
+=item B<subtype ($name, $parent, $where_clause)>
 
-=item B<from>
+This creates a named subtype. 
 
-=item B<via>
+=item B<subtype ($parent, $where_clause)>
 
-=back
+This creates an unnamed subtype and will return the type 
+constraint meta-object, which will be an instance of 
+L<Moose::Meta::TypeConstraint>. 
 
-=head2 Built-in Type Constraints
+=item B<as>
 
-=over 4
+This is just sugar for the type constraint construction syntax.
 
-=item B<Any>
+=item B<where>
 
-=item B<Value>
+This is just sugar for the type constraint construction syntax.
 
-=item B<Int>
+=back
 
-=item B<Str>
+=head2 Type Coercion Constructors
 
-=item B<Ref>
+Type constraints can also contain type coercions as well. In most 
+cases Moose will run the type-coercion code first, followed by the 
+type constraint check. This feature should be used carefully as it 
+is very powerful and could easily take off a limb if you are not 
+careful.
 
-=item B<ArrayRef>
+See the L<SYNOPOSIS> for an example of how to use these.
 
-=item B<CodeRef>
+=over 4
 
-=item B<HashRef>
+=item B<coerce>
 
-=item B<RegexpRef>
+=item B<from>
 
-=item B<ScalarRef>
+This is just sugar for the type coercion construction syntax.
+
+=item B<via>
 
-=item B<Object>
+This is just sugar for the type coercion construction syntax.
 
 =back
 
index e145a6e..259689f 100644 (file)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 21;
+use Test::More tests => 27;
 use Test::Exception;
 
 use Scalar::Util 'isweak';
@@ -41,6 +41,22 @@ BEGIN {
         my ($self, $tree) = @_;
            $tree->parent($self) if defined $tree;   
        };
+       
+       sub BUILD {
+           my ($self, %params) = @_;
+           if ($params{parent}) {
+               # yeah this is a little 
+               # weird I know, but I wanted
+               # to check the weaken stuff 
+               # in the constructor :)
+               if ($params{parent}->has_left) {
+                   $params{parent}->right($self);                  
+               }
+               else {
+                   $params{parent}->left($self);                   
+               }
+           }
+       }
 }
 
 my $root = BinaryTree->new();
@@ -83,3 +99,15 @@ ok($right->has_parent, '... rights has a parent');
 is($right->parent, $root, '... rights parent is the root');
 
 ok(isweak($right->{parent}), '... parent is a weakened ref');
+
+my $left_left = BinaryTree->new(parent => $left);
+isa_ok($left_left, 'BinaryTree');
+
+ok($left_left->has_parent, '... left does have a parent');
+
+is($left_left->parent, $left, '... got a parent node (and it is $left)');
+ok($left->has_left, '... we have a left node now');
+is($left->left, $left_left, '... got a left node (and it is $left_left)');
+
+ok(isweak($left_left->{parent}), '... parent is a weakened ref');
+
index be71ec3..de2a463 100644 (file)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 16;
+use Test::More tests => 20;
 use Test::Exception;
 
 BEGIN {
@@ -27,6 +27,8 @@ foreach my $function (qw(
                             before after around
                             blessed confess
                                                 type subtype as where
+                                                coerce from via
+                                                find_type_constraint
                             )) {
     ok(!Foo->meta->has_method($function), '... the meta does not treat "' . $function . '" as a method');
 }