changed code in anticipation of the new parameterize stuff in Moose/trunk, changed...
[gitmo/MooseX-Types.git] / lib / MooseX / Types.pm
index 5b64c50..364faa2 100644 (file)
@@ -19,7 +19,7 @@ use Carp::Clan                      qw( ^MooseX::Types );
 
 use namespace::clean -except => [qw( meta )];
 
-our $VERSION = 0.05;
+our $VERSION = 0.06;
 
 my $UndefMsg = q{Action for type '%s' not yet defined in library '%s'};
 
@@ -31,7 +31,11 @@ my $UndefMsg = q{Action for type '%s' not yet defined in library '%s'};
 
   # predeclare our own types
   use MooseX::Types 
-      -declare => [qw( PositiveInt NegativeInt )];
+    -declare => [qw(
+        PositiveInt NegativeInt
+        ArrayRefOfPositiveInt ArrayRefOfAtLeastThreeNegativeInts
+        LotsOfInnerConstraints StrOrArrayRef
+    )];
 
   # import builtin types
   use MooseX::Types::Moose 'Int';
@@ -52,6 +56,23 @@ my $UndefMsg = q{Action for type '%s' not yet defined in library '%s'};
       from Int,
           via { 1 };
 
+  # with parameterized constraints.  Please note the containing '(...)'
+  
+  subtype ArrayRefOfPositiveInt,
+    as (ArrayRef[PositiveInt]);
+    
+  subtype ArrayRefOfAtLeastThreeNegativeInts,
+    as (ArrayRef[NegativeInt]),
+    where { scalar(@$_) > 2 };
+
+  subtype LotsOfInnerConstraints,
+    as (ArrayRef[ArrayRef[HashRef[Int]]]);
+    
+  # with TypeConstraint Unions
+  
+  subtype StrOrArrayRef,
+    as Str|ArrayRef;
+
   1;
 
 =head2 Usage
@@ -244,6 +265,44 @@ type does not yet exist.
 
 =back
 
+=head1 NOTES REGARDING PARAMETERIZED CONSTRAINTS
+
+L<MooseX::Types> uses L<MooseX::Types::TypeDecorator> to do some overloading
+which generally allows you to easily create types with parameters such as:
+
+    subtype ParameterType,
+      as (ArrayRef[Int]);
+
+However, due to an outstanding issue you will need to wrap the parameterized
+type inside parenthesis, as in the example above.  Hopefully this limitation
+will be lifted in a future version of this module.
+
+If you are using paramterized types in the options section of an attribute
+declaration, the parenthesis are not needed:
+
+    use Moose;
+    use MooseX::Types::Moose qw(HashRef Int);
+    
+    has 'attr' => (isa=>HashRef[Str]);
+
+=head1 NOTES REGARDING TYPE UNIONS
+
+L<MooseX::Types> uses L<MooseX::Types::TypeDecorator> to do some overloading
+which generally allows you to easily create union types:
+
+  subtype StrOrArrayRef,
+    as Str|ArrayRef;    
+
+As with parameterized constrains, this overloading extends to modules using the
+types you define in a type library.
+
+    use Moose;
+    use MooseX::Types::Moose qw(HashRef Int);
+    
+    has 'attr' => (isa=>HashRef|Int);
+
+And everything should just work as you'd think.
+    
 =head1 METHODS
 
 =head2 import
@@ -300,25 +359,62 @@ yet defined.
 
 =cut
 
-use Data::Dump qw/dump/;
-
 sub type_export_generator {
-    my ($class, $type, $full) = @_;
+    my ($class, $type, $name) = @_;
     return sub {
-        ## todo, this needs to be some sort of ->process_args on the actual
-        ## containing type constraints.  This is ugly proof of concept
-        if(my $param = shift @_) {
-            #my @tc_args = map { find_type_constraint($full) } @args;
-            $full = $full .'['.  $param->[0]->name .']';
+        my $type_constraint;
+        if(defined(my $params = shift @_)) {
+            if(ref $params eq 'ARRAY') {
+                $type_constraint = $class->create_arged_type_constraint($name, @$params);
+            } else {
+                croak 'Arguments must be an ArrayRef, not '. ref $params;
+            }
+        } else {
+            $type_constraint = $class->create_base_type_constraint($name);
         }
+        $type_constraint = defined($type_constraint) ? $type_constraint
+         : MooseX::Types::UndefinedType->new($name);
+         
+        return $class->create_type_decorator($type_constraint);
         
-        my $type_constraint = find_type_constraint($full)
-         || MooseX::Types::UndefinedType->new($full);
-
-        return MooseX::Types::TypeDecorator->new(type_constraint=>$type_constraint);
     };
 }
 
+=head2 create_arged_type_constraint ($name, @args)
+
+Given a String $name with @args find the matching typeconstraint.
+
+=cut
+
+sub create_arged_type_constraint {
+    my ($class, $name, @args) = @_;
+    my $type_constraint = Moose::Util::TypeConstraints::find_or_create_type_constraint($name);
+       return $type_constraint->parameterize(@args)
+}
+
+=head2 create_base_type_constraint ($name)
+
+Given a String $name, find the matching typeconstraint.
+
+=cut
+
+sub create_base_type_constraint {
+    my ($class, $name) = @_;
+    return find_type_constraint($name);
+}
+
+=head2 create_type_decorator ($type_constraint)
+
+Given a $type_constraint, return a lightweight L<MooseX::Types::TypeDecorator>
+instance.
+
+=cut
+
+sub create_type_decorator {
+    my ($class, $type_constraint) = @_;
+    return MooseX::Types::TypeDecorator->new($type_constraint);
+}
+
 =head2 coercion_export_generator
 
 This generates a coercion handler function, e.g. C<to_Int($value)>. 
@@ -378,6 +474,8 @@ L<Sub::Exporter>
 Robert 'phaylon' Sedlacek C<E<lt>rs@474.atE<gt>>, with many thanks to
 the C<#moose> cabal on C<irc.perl.org>.
 
+Additional features by John Napiorkowski (jnapiorkowski) <jjnapiork@cpan.org>.
+
 =head1 LICENSE
 
 This program is free software; you can redistribute it and/or modify