是否有一种优雅的方法来指定子程序参数的默认值?
目前,我使用以下方法:
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} //= [];
}
当有很多选择时,它看起来有点难看。我宁愿做
sub func2 {
my ( $arg1, $arg2, $opt ) = process_args(
opt1 => "no option", opt2 => 1, opt3 => []
);
}
我能想出的最好的方法是:
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);
}
但现在我遇到了另一个问题,我必须将\@_
和非选项参数的数量(此处为2)传递给process_args
..
答案 0 :(得分:6)
sub func1 {
my $arg1 = shift;
my $arg2 = shift;
my %opt = (
opt1 => 'default',
opt2 => 'default',
@_
);
或者,您可以使用Params::Validate。
答案 1 :(得分:3)
我不记得看到一个明确写的子程序来处理子程序参数。你有Ruby背景吗?
您可以通过默认列表定义选项哈希,然后在@_
中传递任何内容。喜欢这个
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 => [],
@_,
);
}
另一种机制,如果你想对不支持的参数进行警告,就是要做很多事情,但是使用delete
,并确保之后哈希是空的,就像这样
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;
}
<强>输出强>
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
答案 2 :(得分:1)
尝试:
# isolate the default options
{
my %default_options = (
opt1 => 'default for opt1',
opt2 => 'default for opt2',
);
sub func1 {
my $arg1 = shift @_;
my $arg2 = shift @_;
# set options
my %opt = %default_options;
if( my %given_opts = @_ ){
for my $key ( keys %opt ){
if( exists $given_opts{$key} ){
$opt{$key} = $given_opts{$key};
}
}
}
# rest of func1
}
}