Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
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; } }

In reply to Handling named function arguments by tilly

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (7)
As of 2024-04-16 18:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found