# 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
}, \@_
);
# ...
}
####
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...
####
restart_server({
-host => $host,
-port => $port,
-timeout => $timeout
}); # works
restart_server([
Host => $host,
Port => $port,
Timeout => $timeout
]); # so does this...
####
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 parameters
# 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;
}