basic-type-coercion
Stevan Little [Sun, 19 Mar 2006 16:26:10 +0000 (16:26 +0000)]
lib/Moose.pm
lib/Moose/Util/TypeConstraints.pm
t/054_util_type_coercion.t

index 1127479..b692b10 100644 (file)
@@ -77,11 +77,22 @@ sub import {
                        }                       
                }
                if (exists $options{isa}) {
+                   # allow for anon-subtypes here ...
                    if (reftype($options{isa}) && reftype($options{isa}) eq 'CODE') {
                                $options{type_constraint} = $options{isa};
                        }
                        else {
-                $options{type_constraint} = Moose::Util::TypeConstraints::find_type_constraint($options{isa});
+                           # otherwise assume it is a constraint
+                           my $constraint = Moose::Util::TypeConstraints::find_type_constraint($options{isa});
+                           # if the constraing it not found ....
+                           unless (defined $constraint) {
+                               # assume it is a foreign class, and make 
+                               # an anon constraint for it 
+                               $constraint = Moose::Util::TypeConstraints::subtype(
+                                   Object => Moose::Util::TypeConstraints::where { $_->isa($constraint) }
+                       );
+                           }
+                $options{type_constraint} = $constraint;
                        }
                }
                $meta->add_attribute($name, %options) 
@@ -213,6 +224,14 @@ originally, I just ran with it.
 
 =back
 
+=head1 SEE ALSO
+
+=over 4
+
+=item L<http://forum2.org/moose/>
+
+=back
+
 =head1 BUGS
 
 All complex software has bugs lurking in it, and this module is no 
index 3e6a854..f21e348 100644 (file)
@@ -4,6 +4,7 @@ package Moose::Util::TypeConstraints;
 use strict;
 use warnings;
 
+use Carp         'confess';
 use Sub::Name    'subname';
 use Scalar::Util 'blessed';
 
@@ -91,9 +92,24 @@ sub subtype ($$;$) {
 }
 
 sub coerce {
-    my ($type_name, %coercion_map) = @_;
+    my ($type_name, @coercion_map) = @_;
+    my @coercions;
+    while (@coercion_map) {
+        my ($constraint_name, $action) = splice(@coercion_map, 0, 2);
+        my $constraint = find_type_constraint($constraint_name);
+        (defined $constraint)
+            || confess "Could not find the type constraint ($constraint_name)";
+        push @coercions => [  $constraint, $action ];
+    }
     register_type_coercion($type_name, sub { 
-        %coercion_map 
+        my $thing = shift;
+        foreach my $coercion (@coercions) {
+            my ($constraint, $converter) = @$coercion;
+            if (defined $constraint->($thing)) {
+                return $converter->($thing);
+            }
+        }
+        return $thing;
     });
 }
 
index 5b9b62e..a981b10 100644 (file)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 6;
+use Test::More tests => 14;
 use Test::Exception;
 
 BEGIN {
@@ -42,24 +42,36 @@ ok(!Header({}), '... this did not pass the type test');
 my $coercion = Moose::Util::TypeConstraints::find_type_coercion('Header');
 is(ref($coercion), 'CODE', '... got the right type of coercion');
 
-#{
-#    my $coerced = $coercion->([ 1, 2, 3 ]);
-#    isa_ok($coerced, 'HTTPHeader');
-#
-#    is_deeply(
-#        $coerced->array(),
-#        [ 1, 2, 3 ],
-#        '... got the right array');
-#    is($coerced->hash(), undef, '... nothing assigned to the hash');        
-#}
-#
-#{
-#    my $coerced = $coercion->({ one => 1, two => 2, three => 3 });
-#    isa_ok($coerced, 'HTTPHeader');
-#    
-#    is_deeply(
-#        $coerced->hash(),
-#        { one => 1, two => 2, three => 3 },
-#        '... got the right hash');
-#    is($coerced->array(), undef, '... nothing assigned to the array');        
-#}
+{
+    my $coerced = $coercion->([ 1, 2, 3 ]);
+    isa_ok($coerced, 'HTTPHeader');
+
+    is_deeply(
+        $coerced->array(),
+        [ 1, 2, 3 ],
+        '... got the right array');
+    is($coerced->hash(), undef, '... nothing assigned to the hash');        
+}
+
+{
+    my $coerced = $coercion->({ one => 1, two => 2, three => 3 });
+    isa_ok($coerced, 'HTTPHeader');
+    
+    is_deeply(
+        $coerced->hash(),
+        { one => 1, two => 2, three => 3 },
+        '... got the right hash');
+    is($coerced->array(), undef, '... nothing assigned to the array');        
+}
+
+{
+    my $scalar_ref = \(my $var);
+    my $coerced = $coercion->($scalar_ref);
+    is($coerced, $scalar_ref, '... got back what we put in');
+}
+
+{
+    my $coerced = $coercion->("Foo");
+    is($coerced, "Foo", '... got back what we put in');
+}
+