我有一个子程序,原型如下:
sub printFoo(%) {
my (%hashFoo)=@_;
# do stuff with the hash
}
但我希望可以选择传递第二个标量参数:
sub printFoo(%;$) {
my (%hashFoo,$optionalArg)=@_;
# do stuff with the hash and the optional arg
}
据我所知,在警告模式下,这是禁忌,但我不确定原因。
我想我可以使用全局变量标志,但有关如何优雅地完成此类函数签名的任何建议吗?
答案 0 :(得分:4)
我不知道这是否算得很优雅,但......
sub printFoo {
my $optionalArg;
if (@_ % 2 != 0) {
$optionalArg = pop @_;
}
my %hashFoo = @_;
...
}
带有哈希引用的原型也可以。您仍然会使用散列调用该函数,但您必须记住您的sub将接收的第一个散列arg作为散列引用。
sub printFoo (\%;$) { # call as printFoo %foo or printFoo %foo, 42
my ($hashFooRef, $optionalArg) = @_;
my %hashFoo = %$hashFooRef;
...
}
答案 1 :(得分:2)
优雅地处理可选参数:
sub do_something {
my (%params) = @_;
my $debug = delete $params{debug} || 0;
# do something with %params...
}
答案 2 :(得分:2)
如果您使用散列引用,因为其他人建议将其作为第一个arg,那么在接受它们之后检查args是微不足道的:
use strict;
use warnings;
my %hash = (a => 1, b => 2,);
my $scalar = 1;
printFoo(\%hash, $scalar);
sub printFoo {
my ($href, $opt) = @_;
if(ref $href ne 'HASH' || $opt && ref \$opt ne 'SCALAR'){
die "Usage: printFoo(hashref, optional_scalar)\n";
}
...
}
答案 3 :(得分:1)
我同意Hakon Haegland关于使用散列引用的看法。为了得到你可以选择的多个参数,你需要传递多个标量,而不是基本上是一个列表,后跟其他东西。
我认为这与你是否应该使用原型的问题无关。通过标记这个警告系统帮了你一个忙,但我99.44%肯定即使你丢弃原型它也行不通。您仍然不会在可选参数中得到一个值。