This subroutine provides a simple way to write functions in Perl that take named parameters. It doesn't perform any validation like the Params::Validate module does, but it strives to support the most flexible interface possible.
Here's an example of its usage:
# this sub takes named parameters: sub restart_server { # the variables to store the parameter values in: my ($host, $port, $timeout); # extract the parameter values: get_named_params({ host => \$host, port => \$port, timeout => \$timeout }, \@_ ); # ... }
It supports Tk-style "-paramname => $value" parameters, libnet-style "ParamName => $value" parameters, and LWP-style "param_name => $value" parameters all transparently:
restart_server( -host => $host, -port => $port, -timeout => $timeout ); # works restart_server( Host => $host, Port => $port, Timeout => $timeout ); # so does this... restart_server( host => $host, port => $port, timeout => $timeout ); # and this...
This routine was written with efficiency in mind. Instead of just returning the values outright, it takes references to variables where they get stored, and the argument list is passed in as an array or hash reference. Keeping with this theme, the named parameters themselves can be passed to your subroutine as a hash/array reference for even better performance:
restart_server({ -host => $host, -port => $port, -timeout => $timeout }); # works restart_server([ Host => $host, Port => $port, Timeout => $timeout ]); # so does this...
As mentioned above, get_named_params() doesn't perform any validation, so you'll have to check the destination variables for undef-ness and proper values yourself, or use Params::Validate if you can't be bothered to do that.
sub get_named_params { my ($destinations, $arg_list) = @_; croak "Arguments weren't sent as a reference to a hash or array." unless (ref $arg_list eq 'ARRAY' or ref $arg_list eq 'HASH'); # this will store a reference to a hash containing the named param +eters # passed to your sub: my $params_hashref; if (ref $arg_list eq 'ARRAY') { if (@$arg_list == 1) { # The callers of your sub can optionally pass their # named parameters as a hash or array references, in # which case @_ contains the reference as its first and # only element: my $ref = $$arg_list[0]; my $ref_type = ref $ref; croak( 'Odd number of arguments sent to sub ' . 'expecting named parameters.' ) unless $ref_type; croak ( "Bad refernce type \"$ref_type\" for named " . "parameters. Pass them instead as either a " . "hash or array reference." ) unless ($ref_type eq 'ARRAY' or $ref_type eq 'HASH'); $params_hashref = (ref $ref eq 'ARRAY') ? { @$ref } : $ref; } else { $params_hashref = { @$arg_list }; } } else { $params_hashref = $arg_list; } my %name_translation_table; foreach my $destination_name (keys %$destinations) { my $stripped_name = strip_param_name($destination_name); $name_translation_table{$stripped_name} = $destination_name; } foreach my $supplied_name (keys %$params_hashref) { my $stripped_name = strip_param_name($supplied_name); next unless (exists $name_translation_table{$stripped_name}); my $destination_name = $name_translation_table{$stripped_name} +; my $destination_ref = $destinations->{$destination_name}; $$destination_ref = $params_hashref->{$supplied_name}; } } sub strip_param_name { my $stripped_name = lc shift; $stripped_name =~ s/_//g; $stripped_name =~ s/^-//; return $stripped_name; }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Case-insensitive, dash-optional named parameters for your functions
by jdporter (Paladin) on Nov 08, 2004 at 04:14 UTC | |
by William G. Davis (Friar) on Nov 08, 2004 at 08:57 UTC | |
by ikegami (Patriarch) on Nov 09, 2004 at 15:06 UTC | |
by William G. Davis (Friar) on Nov 11, 2004 at 22:37 UTC | |
|
Re: Case-insensitive, dash-optional named parameters for your functions
by iblech (Friar) on Nov 08, 2004 at 16:11 UTC |