From: Dave Rolsky Date: Mon, 29 Nov 2010 22:28:54 +0000 (-0600) Subject: Add MX_PARAMS_VALIDATE_ALLOW_EXTRA X-Git-Tag: v0.15~11 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMooseX-Params-Validate.git;a=commitdiff_plain;h=df3c7e86e3ace056979d28a5acb2d130fc57ab7c Add MX_PARAMS_VALIDATE_ALLOW_EXTRA --- diff --git a/ChangeLog b/ChangeLog index da4ee72..0643c5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ Revision history for Perl extension MooseX-Params-Validate +0.15 + - Add MX_PARAMS_VALIDATE_ALLOW_EXTRA which allows extra parameters in + validation calls (like allow_extra for Params::Validate). + 0.14 Sun. Mar. 18, 2010 - The validated_hash method failed when called on in an overloaded stringify method. Patch by Ian Sillitoe. RT #52565. diff --git a/lib/MooseX/Params/Validate.pm b/lib/MooseX/Params/Validate.pm index b7293e5..ad9c755 100644 --- a/lib/MooseX/Params/Validate.pm +++ b/lib/MooseX/Params/Validate.pm @@ -29,6 +29,8 @@ sub validated_hash { my $cache_key = _cache_key( \%spec ); + my $allow_extra = delete $spec{MX_PARAMS_VALIDATE_ALLOW_EXTRA}; + if ( exists $CACHED_SPECS{$cache_key} ) { ( ref $CACHED_SPECS{$cache_key} eq 'HASH' ) || confess @@ -55,9 +57,10 @@ sub validated_hash { for grep { $spec{$_}{coerce} && exists $args{$_} } keys %spec; %args = Params::Validate::validate_with( - params => \%args, - spec => \%spec, - called => _caller_name(), + params => \%args, + spec => \%spec, + allow_extra => $allow_extra, + called => _caller_name(), ); return ( ( defined $instance ? $instance : () ), %args ); @@ -72,6 +75,8 @@ sub validated_list { my $cache_key = _cache_key( \%spec ); + my $allow_extra = delete $spec{MX_PARAMS_VALIDATE_ALLOW_EXTRA}; + my @ordered_spec; if ( exists $CACHED_SPECS{$cache_key} ) { ( ref $CACHED_SPECS{$cache_key} eq 'ARRAY' ) @@ -102,9 +107,10 @@ sub validated_list { for grep { $spec{$_}{coerce} && exists $args{$_} } keys %spec; %args = Params::Validate::validate_with( - params => \%args, - spec => \%spec, - called => _caller_name(), + params => \%args, + spec => \%spec, + allow_extra => $allow_extra, + called => _caller_name(), ); return ( @@ -125,6 +131,8 @@ sub pos_validated_list { my $cache_key = _cache_key( \%extra ); + my $allow_extra = delete $extra{MX_PARAMS_VALIDATE_ALLOW_EXTRA}; + my @pv_spec; if ( exists $CACHED_SPECS{$cache_key} ) { ( ref $CACHED_SPECS{$cache_key} eq 'ARRAY' ) @@ -149,9 +157,10 @@ sub pos_validated_list { for grep { $pv_spec[$_] && $pv_spec[$_]{coerce} } 0 .. $#args; @args = Params::Validate::validate_with( - params => \@args, - spec => \@pv_spec, - called => _caller_name(), + params => \@args, + spec => \@pv_spec, + allow_extra => $allow_extra, + called => _caller_name(), ); return @args; @@ -389,6 +398,18 @@ below, simply pass them after the list of parameter validation specs: =back +=head1 ALLOWING EXTRA PARAMETERS + +By default, any parameters not mentioned in the parameter spec cause this +module to throw an error. However, you can have have this module simply ignore +them by setting C to a true value when calling +a validation subroutine. + +When calling C or C the extra parameters +are simply returned in the hash or list as appropriate. However, when you call +C the extra parameters will not be returned at all. You can +get them by looking at the original value of C<@_>. + =head1 EXPORTS By default, this module exports the C, @@ -400,11 +421,10 @@ them. =head1 IMPORTANT NOTE ON CACHING -When C or C are called the first time, the -parameter spec is prepared and cached to avoid unnecessary -regeneration. It uses the fully qualified name of the subroutine -(package + subname) as the cache key. In 99.999% of the use cases for -this module, that will be the right thing to do. +When a validation subroutine is called the first time, the parameter spec is +prepared and cached to avoid unnecessary regeneration. It uses the fully +qualified name of the subroutine (package + subname) as the cache key. In +99.999% of the use cases for this module, that will be the right thing to do. However, I have (ab)used this module occasionally to handle dynamic sets of parameters. In this special use case you can do a couple diff --git a/t/011_allow_extra.t b/t/011_allow_extra.t new file mode 100644 index 0000000..f6b280a --- /dev/null +++ b/t/011_allow_extra.t @@ -0,0 +1,50 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More; +use Test::Fatal; + +use MooseX::Params::Validate qw( validated_hash ); + +{ + sub foo { + my %params = validated_hash( + \@_, + x => { isa => 'Int' }, + y => { isa => 'Int' }, + ); + \%params; + } + + sub bar { + my %params = validated_hash( + \@_, + x => { isa => 'Int' }, + y => { isa => 'Int' }, + MX_PARAMS_VALIDATE_ALLOW_EXTRA => 1, + ); + \%params; + } +} + +is_deeply( + bar( x => 42, y => 1 ), + { x => 42, y => 1 }, + 'bar returns expected values with no extra params' +); + +is_deeply( + bar( x => 42, y => 1, z => 'whatever' ), + { x => 42, y => 1, z => 'whatever' }, + 'bar returns expected values with extra params' +); + +like( + exception { foo( x => 42, y => 1, z => 'whatever' ) }, + qr/The following parameter .+ listed in the validation options: z/, + 'foo rejects extra params' +); + +done_testing();