Is there an elegant way to specify default values for subroutine arguments?
Currently, I am using the following approach:
use strict;
use warnings;
func1( "arg1", "arg2", opt1 => "first option", opt2 => 0 );
sub func1 {
my ( $arg1, $arg2, %opt ) = @_;
$opt{opt1} //= "no option";
$opt{opt2} //= 1;
$opt{opt3} //= [];
}
which looks a little bit ugly, when there are many options. I would rather like to do
sub func2 {
my ( $arg1, $arg2, $opt ) = process_args(
opt1 => "no option", opt2 => 1, opt3 => []
);
}
The best I could come up with for this approach was:
sub func2 {
my ( $arg1, $arg2, $opt ) = process_args(
\@_, 2, opt1 => "no option", opt2 => 1, opt3 => []
);
}
sub process_args {
my ($a, $n, %opt_info ) = @_;
my @b = splice @$a, 0, $n;
my %opt = @$a;
for my $key (keys %opt_info) {
$opt{$key} //= $opt_info{$key};
}
return (@b, \%opt);
}
but now I got the other problem, that I must pass \@_ and the number of non-option arguments ( here 2 ), to process_args..
sub func1 {
my $arg1 = shift;
my $arg2 = shift;
my %opt = (
opt1 => 'default',
opt2 => 'default',
@_
);
Or, you can use Params::Validate.
I don't remember seeing a subroutine written expressly to handle subroutine parameters. Do you have a Ruby background?
You can define the options hash by a list of its defaults, followed by anything passed in @_. Like this
use strict;
use warnings;
func1( "arg1", "arg2", opt1 => "first option", opt2 => 0 );
sub func1 {
my ( $arg1, $arg2 ) = splice @_, 0, 2;
my %opts = (
opt1 => "no option",
opt2 => 1,
opt3 => [],
@_,
);
}
Another mechanism, if you want to warn against unsupported paremeters, is to do much as you have, but use delete, and to ensure that the hash is empty afterwards, like this
use strict;
use warnings;
use Data::Dump;
use Carp 'croak';
func1( "arg1", "arg2", opt9 => 9 );
sub func1 {
my ( $arg1, $arg2, %opt ) = @_;
my $opt1 = delete $opt{opt1} // 'no option';
my $opt2 = delete $opt{opt2} // 1;
my $opt3 = delete $opt{opt3} // [];
croak "Unexpected parameters: ", join ',', keys %opt if keys %opt;
}
output
Unexpected parameters: opt9 at E:\Perl\source\args.pl line 16.
main::func1("arg1", "arg2", "opt9", 9) called at E:\Perl\source\args.pl line 7
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With