# 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; }