Skip to content

Commit

Permalink
Allow coderefs to be passed via "defaults"
Browse files Browse the repository at this point in the history
Sometimes it's useful to execute something when a value is not passed at the
command line.  This patch provides an easy way to do that, by allowing
coderefs to be passed via "default", and executed if no value is provided.
  • Loading branch information
rsrchboy committed Sep 12, 2010
1 parent ea1fc0b commit 21db950
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
19 changes: 17 additions & 2 deletions lib/opts.pm
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ sub opts {
# XXX: should we provide ways to check the type of invocant?
}

# track our coderef defaults
my %default_subs;

my @options;
my %requireds;
my %generaters;
Expand All @@ -50,8 +53,16 @@ sub opts {
my $rule = _compile_rule($_[$i+1]);

if (exists $rule->{default}) {
$_[$i] = $rule->{default};

if (ref $rule->{default} && ref $rule->{default} eq 'CODE') {
$default_subs{$i} = $rule->{default};
$_[$i] = undef;
}
else {
$_[$i] = $rule->{default};
}
}

if (exists $rule->{required}) {
$requireds{$name} = $i;
}
Expand All @@ -69,6 +80,9 @@ sub opts {
local $SIG{__WARN__} = sub { $err = shift };
GetOptions(@options) or Carp::croak($err);

do { $_[$_] = $default_subs{$_}->() unless defined $_[$_] }
for keys %default_subs;

while ( my ($name, $idx) = each %requireds ) {
unless (defined($_[$idx])) {
Carp::croak("missing mandatory parameter named '\$$name'");
Expand Down Expand Up @@ -180,7 +194,8 @@ opts is DSL for command line option.
define option value is required.
default
define options default value.
define options default value. If passed a coderef, it
will be executed if no value is provided on the command line.
alias
define option param's alias.
Expand Down
12 changes: 10 additions & 2 deletions t/010_simple/04_default.t
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@ use opts;
use Test::More;
use Test::Exception;

is foo(), 99;
is default(), 99;
is default_as_coderef(), 99;

done_testing;

exit;

sub foo {
sub default {
opts my $p => { isa => 'Int', default => 99 };
return $p;
}

sub default_as_coderef {
opts my $x => { isa => 'Int', default => sub { 99 } };
return $x;
}

0 comments on commit 21db950

Please sign in to comment.