Accept hash/array ref for params to validate
Dave Rolsky [Sat, 29 Jan 2011 17:30:32 +0000 (11:30 -0600)]
lib/MooseX/Params/Validate.pm
t/012_ref_as_first_param.t [new file with mode: 0644]

index 25fb20a..5153916 100644 (file)
@@ -5,7 +5,7 @@ use warnings;
 
 use Carp 'confess';
 use Devel::Caller 'caller_cv';
-use Scalar::Util 'blessed', 'refaddr';
+use Scalar::Util 'blessed', 'refaddr', 'reftype';
 
 use Moose::Util::TypeConstraints qw( find_type_constraint class_type role_type );
 use Params::Validate             ();
@@ -48,7 +48,10 @@ sub validated_hash {
     my $instance;
     $instance = shift @$args if blessed $args->[0];
 
-    my %args = @$args;
+    my %args 
+        = @$args == 1
+        && ref $args->[0]
+        && reftype( $args->[0] ) eq 'HASH' ? %{ $args->[0] } : @$args;
 
     $args{$_} = $spec{$_}{constraint}->coerce( $args{$_} )
         for grep { $spec{$_}{coerce} && exists $args{$_} } keys %spec;
@@ -98,7 +101,10 @@ sub validated_list {
     my $instance;
     $instance = shift @$args if blessed $args->[0];
 
-    my %args = @$args;
+    my %args 
+        = @$args == 1
+        && ref $args->[0]
+        && reftype( $args->[0] ) eq 'HASH' ? %{ $args->[0] } : @$args;
 
     $args{$_} = $spec{$_}{constraint}->coerce( $args{$_} )
         for grep { $spec{$_}{coerce} && exists $args{$_} } keys %spec;
@@ -148,7 +154,10 @@ sub pos_validated_list {
             if $should_cache;
     }
 
-    my @args = @{$args};
+    my @args 
+        = @$args == 1
+        && ref $args->[0]
+        && reftype( $args->[0] ) eq 'ARRAY' ? @{ $args->[0] } : @$args;
 
     $args[$_] = $pv_spec[$_]{constraint}->coerce( $args[$_] )
         for grep { $pv_spec[$_] && $pv_spec[$_]{coerce} } 0 .. $#args;
diff --git a/t/012_ref_as_first_param.t b/t/012_ref_as_first_param.t
new file mode 100644 (file)
index 0000000..e934395
--- /dev/null
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Fatal;
+
+{
+    use MooseX::Params::Validate;
+
+    sub foo {
+        my ( $x, $y ) = validated_list(
+            \@_,
+            x => { isa => 'Any' },
+            y => { isa => 'Any' },
+        );
+
+        return { x => $x, y => $y };
+    }
+
+    sub bar {
+        my %p = validated_hash(
+            \@_,
+            x => { isa => 'Any' },
+            y => { isa => 'Any' },
+        );
+
+        return \%p;
+    }
+
+    sub baz {
+        my ( $x, $y ) = pos_validated_list(
+            \@_,
+            { isa => 'Any' },
+            { isa => 'Any' },
+        );
+
+        return { x => $x, y => $y };
+    }
+}
+
+is_deeply(
+    foo( x => 42, y => 84 ),
+    { x => 42, y => 84 },
+    'validated_list accepts a plain hash'
+);
+
+is_deeply(
+    foo( { x => 42, y => 84 } ),
+    { x => 42, y => 84 },
+    'validated_list accepts a hash reference'
+);
+
+is_deeply(
+    bar( x => 42, y => 84 ),
+    { x => 42, y => 84 },
+    'validated_hash accepts a plain hash'
+);
+
+is_deeply(
+    bar( { x => 42, y => 84 } ),
+    { x => 42, y => 84 },
+    'validated_hash accepts a hash reference'
+);
+
+is_deeply(
+    baz( 42, 84 ),
+    { x => 42, y => 84 },
+    'pos_validated_list accepts a plain array'
+);
+
+is_deeply(
+    baz( [42, 84] ),
+    { x => 42, y => 84 },
+    'pos_validated_list accepts a array reference'
+);
+
+done_testing();