Rex-Dondley-ProcessTaskArgs
view release on metacpan or search on metacpan
lib/Rex/Dondley/ProcessTaskArgs.pm view on Meta::CPAN
our @EXPORT = 'process_task_args';
use Log::Log4perl::Shortcuts qw(:all);
# checks validity of args passed to functions and assigns them to appropriate keys
# Accept 3 sets of args:
# first arg is reference to parameters passed by user to task
# next set of args is a list of allowed params which can also indicate required params
# last arg is an array hash for default values corresponding to each allowed params
sub process_task_args {
if (!$_[0] || (ref $_[0]) ne 'ARRAY') {
die 'First argument must be an array ref to user supplied arguments.';
}
# standardize the argument data structure
if (ref $_[0] && ref $_[0]->[0] ne 'HASH') {
my @args = @{$_[0]};
shift @_;
@_ = ([ {}, \@args,], @_ );
}
my $passed_in = shift @_;
my %passed_params = %{$passed_in->[0]};
my @unkeyed_args = @{$passed_in->[1]};
my @defaults = ref $_[-1] ? @{$_[-1]} : ();
pop @_ if @defaults;
my @valid_args = @_;
my @key_list = grep { $_ && $_ ne '1' && (ref $_) ne 'ARRAY' } @_;
my %defaults = ();
my $count = 0;
foreach my $key (@key_list) {
$defaults{$key} = $defaults[$count++];
}
# create a hash of valid and required keys
# assumes all values are not required if @valid_args do not contain required value
my @ordered_keys;
my %valid_keys = ();
if ((exists $valid_args[1] && ($valid_args[1] !~ /^0|1$/)) || scalar @valid_args == 1) { # checks to see if list contains required values
foreach my $arg (@valid_args) {
$valid_keys{$arg} = 0;
@ordered_keys = @valid_args;
}
} else {
%valid_keys = @valid_args;
my $count = 0;
foreach my $key (@valid_args) {
if (!($count++ % 2)) {
push @ordered_keys, $key;
}
}
}
# check to see if passed parameters are valid
my @invalid_keys;
foreach my $key (keys %passed_params) {
my $is_valid = grep { $_ eq $key } keys %valid_keys;
if (!$is_valid) {
push @invalid_keys, $key;
}
die ("Invalid key(s): '" . join (', ', @invalid_keys) . "' from ". (caller)[1] . ', line ' . (caller)[2]) if @invalid_keys;
}
# Populate the %passed_params hash with @unkeyed_args according
# to same order they were passed to this function via @valid_args.
# Throw error if there are more args than available keys.
if (@unkeyed_args) {
my @all_array_args = @unkeyed_args;
foreach my $array_arg (@unkeyed_args) {
foreach my $vkey (@key_list) {
if (exists $passed_params{$vkey}) {
next;
}
$passed_params{$vkey} = $array_arg;
shift @all_array_args;
last;
}
}
die ('Too many array arguments passed from ' . (caller)[1] . ', line ' . (caller)[2] ) if @all_array_args;
}
# Ensure required args are present
my @reqd_keys = grep { $valid_keys{$_} } keys %valid_keys;
my @missing_keys;
foreach my $rkey(@reqd_keys) {
if (!exists $passed_params{$rkey} || $passed_params{$rkey} eq '1') {
push @missing_keys, $rkey unless $defaults{$rkey};
}
}
die ("Missing required key(s): '" . join (', ', @missing_keys) . "' from " . (caller)[1] . ', line ' . (caller)[2]) if @missing_keys;
# handle edge case when user passes key without value
foreach my $key (keys %passed_params) {
if ($passed_params{$key} && $passed_params{$key} eq '1' && $valid_keys{$key}) {
delete $passed_params{$key};
}
}
my %return_hash = (%defaults, %passed_params);
if (wantarray) {
my @blah = @return_hash{ @ordered_keys };
return @blah;
} else {
return \%return_hash;
}
}
# methods here
1; # Magic true value
# ABSTRACT: easier Rex task argument handling
__END__
=pod
=head1 NAME
Rex::Dondley::ProcessTaskArgs - easier Rex task argument handling
=head1 VERSION
version 0.013
=head1 SYNOPSIS
use Rex::Dondley::ProcessTaskArgs;
task 'some_task' => sub {
# Process args passed to task
my $params = process_task_args( \@_, # arguments passed by user
available_key1 => 1, # a required argument
available_key2 => 0, # an optional argument
# optional array hash for default values
[
'default_value_for_key1',
'default_value_for_key2',
]
);
# Now retrieve the values as usual
my $key1 = $params->{key1};
my $key2 = $params->{key2};
};
# If no arguments are required, list of available keys can be simplified:
task 'another_task' => sub {
my $params = process_task_args( \@_, key1, key2 [ 'default_value_for_key1' ]);
( run in 0.798 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )