What I do is having a function that does destructive manipulation of my arguments:
Call it without a default argument and you have a required key. Put in the default and it is optional. And since it is destructive, it gets rid of the keys and I can use this for a typo check.# Takes a hashref, a key name, and an optional default. # Removes that key from the hash, and returns the value or # the default. Blows up if there is no value or default. sub excise_arg { my $args = shift; my $arg_name = shift; if (exists $args->{$arg_name}) { return delete $args->{$arg_name}; } elsif (@_) { return shift; } else { confess("Missing required argument '$arg_name'"); } }
And now in a function I can do this:# Takes a hashref. Verifies that it is empty sub assert_args_done { my @left = keys %{ $_[0] }; if (@left) { confess("Unexpected arguments '@left' left over"); } }
And if I want to take an existing function and wrap it in one that can handle some things itself and wraps the rest, it is easy. I just excise a few arguments and then pass the rest through untested. As long as they are tested somewhere, typos get checked.sub some_func { my $args = { @_ }; my $name = excise_arg($args, 'name'); # required my $age = excise_arg($args, 'age', undef); # optional assert_args_done($args); # Rest of the code here. }
If anyone has alternate suggestions for how to handle this problem, I am open. This seems to work pretty well, but I have tried several things, and I don't claim that this is perfect.
UPDATE
Thanks Hofmator for catching my obvious typo. That is
what I get for typing something up off of the top of my
head. That is also why I use strict. :-)
In reply to Re (tilly) 2: passing subroutine arguments directly into a hash
by tilly
in thread passing subroutine arguments directly into a hash
by c
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |