views:

288

answers:

1

Hi Perl followers.

I am having trouble getting Params::Validate to work how I want it to.

#!/usr/local/bin/perl -w 
use strict;
use Params::Validate qw/:all/;
use Data::Dumper;

sub foo {
    my %args = validate(@_, {
        bar => {
            default => 99,
            # TODO - Somehow use a callback to return a default if undefined
            # ??!!?? 
            # callbacks => { call_me => sub { return 99 if !defined shift }},
        },
    });

    # $args{bar} //= 99; # Don't want to define default in 2 places

    print Dumper(\%args);
}
foo({ bar => undef });

So how do I set / test for an undef in the args list and replace with the said 'default' value with Params::Validate ??

+2  A: 

You need to be setting $_[0]:

call_me => sub { $_[0] = 99 if not defined $_[0] }

@_ is aliased to the parameters passed in, so you can use this as a reference to the original.

Also,

$args{bar} ||= 99;

would reset bar even if it were 0 or '' (empty string), which doesn't sound like what you want. Using

$args{bar} //= 99;

if you're using perl 5.10 or later would do what you want, though.

Based on your comment of not duplicating the default, the best I could come up with is:

sub foo
{
    unshift @_, bar => undef;
    my %args = validate(@_,
                        {
                            bar => {
                                optional => 1,
                                callbacks => {
                                    call_me => sub { $_[0] = 99 unless defined $_[0] },
                                },
                            },
                        },
                       );
    print Dumper \%args;
}

That seems to work, but I have to admit - it's ugly.

Tanktalus
Is there a way to reference the specs 'default => 99' ? So that if i call foo({ }) then bar is still set and the default value is only specified in one place?
CoffeeMonster