Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Handling named function arguments

by tilly (Archbishop)
on Nov 25, 2000 at 22:55 UTC ( #43323=snippet: print w/ replies, xml ) Need Help??

Description: When you have a function that has quite a few arguments, including a number of defaults, it is often much nicer to use a hash instead of an array. However a risk with that is that someone will mistype a name and their argument will be silently ignored. So ideally instead of just using a hash you want to do internal processing to make sure that the function has been called appropriately.

This snippet takes care of that. It allows you to have required arguments, optional arguments, and to set defaults on some of the optional arguments. Just use it like this:

sub examp_func { my %args = @_; my ($foo, $bar, $baz) = proc_args(\%args, ['foo'], ['bar', 'baz'], {bar => 'default'}); print "foo: $foo\n"; print "bar: $bar\n"; print "baz: $baz\n"; }
Unfortunately you still need to synchronize the order of arguments to the function with the variables that they go in. Barring using some sort of macro-preprocessing facility that looks unavoidable if you want the protection of lexical variables.

TIMTOWTDI, but if you are tempted to use this in a lot of your code you probably should think about whether certain collections of arguments logically belong together in an object of some class...

UPDATE
I am not longer happy with this snippet. The approach that I prefer as of Nov 2001 is in Re (tilly) 2: passing subroutine arguments directly into a hash. YMMV.

use Carp;

# Takes an anon hash of args, an anon array of required fields,
# an optional anon array of optional args, and an optional
# anon hash of defaults.  Returns an array of the determined
# values
sub proc_args {
  my $args = shift;
  my $req = shift;
  my $opt = shift || [];
  my $default = shift || {};
  my @res;
  foreach my $arg (@$req) {
    if (exists $args->{$arg}) {
      push @res, $args->{$arg};
      delete $args->{$arg};
    }
    else {
      confess("Missing required argument $arg");
    }
  }
  foreach my $arg (@$opt) {
    if (exists $args->{$arg}) {
      push @res, $args->{$arg};
      delete $args->{$arg};
    }
    else {
      push @res, $default->{$arg};
    }
  }
  if (%$args) {
    my $bad = join ", ", sort keys %$args;
    confess("Unrecognized arguments: $bad\n");
  }
  else {
    return @res;
  }
}
Comment on Handling named function arguments
Download Code
Re: Handling named function arguments
by brother ab (Scribe) on Nov 27, 2000 at 12:10 UTC

    There exists also Class::ParamParser module which provides the similar functionality (sometimes more and sometimes less).

    -- brother ab

Back to Snippets Section

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://43323]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (16)
As of 2014-07-25 09:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (170 votes), past polls