我想将几个参数(其中一个是可选的)传递给一个函数。我知道的唯一方法是使用列表(@)作为参数。因此,它不包含任何内容或1个元素(永远不会是undef),因此我可以使用以下代码:
sub someFunction($$@) {
my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
...
}
此代码有效,但我觉得这可能不是最好的解决方法
还有其他办法吗?
谢谢。
答案 0 :(得分:37)
Prototypes(您的子声明的($$@)
部分)本身是可选的。它们具有非常特殊的用途,如果您不知道它是什么,最好不要使用它。来自perlsub:
...此功能的目的主要是让您定义子例程 像内置函数一样工作
只需从您的子声明中删除原型,您就可以使用您喜欢的任何参数。
sub someFunction {
my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
if (defined $option_param) {
# do optional things
}
$option_param //= "default optional value";
....
}
答案 1 :(得分:18)
您可以在原型中使用分号来表示所需参数的结束:
sub someFunction($$;$) {
my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
...
}
;
在@
或%
之前是可选的,根据the docs,“吞噬其他所有内容”。
sub someFunction {
my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
...
}
Perl原型有其用途(主要用于向参数提供隐式上下文强制,就像Perl的内置函数那样)。它们应该不用作检查函数是否使用正确数量和类型的参数调用的机制。
答案 2 :(得分:14)
在$parameter
hashref中对参数进行分组是个好主意。如果需要提供多个选项(强制或可选),这将特别有用。
要访问任何参数,只需使用$parameter->{oblig1}
或$$parameter{option2}
。
传递hashrefs使得它在开发时特别方便,因此当需要$oblig3
时,参数的顺序既不会在调用者也不会在sub本身发生变化。比较之前和之后:
# BEFORE $oblig3
--------------------------+-------------------------
# Caller | # Sub
--------------------------+-------------------------
someFunc( $oblig1, | sub {
$oblig2, | my ( $oblig1,
$option1 ); | $oblig2,
| $option1 ) = @_;
| }
--------------------------+-------------------------
# AFTER $oblig3
--------------------------+-------------------------
# Caller | # Sub
--------------------------+-------------------------
someFunc( $oblig1, | sub {
$oblig2, | my ( $oblig1,
$oblig3, | $oblig2,
$option1 ); | $oblig3,
| $option1 ) = @_;
| }
--------------------------+-------------------------
参数顺序在调用者和子函数处都会发生变化,因此需要维护和遵守顺序。
使用hashrefs,无需担心参数顺序:
--------------------------+-------------------------
# Caller | # Sub
--------------------------+-------------------------
someFunc({ oblig1 => 1 | sub {
oblig2 => 2 | my ( $params ) = @_;
option1 => 1 | # No changes to
oblig3 => 7 | # argument passing
}); | }
|
--------------------------+-------------------------
根据子程序的设计需要,可以使用以下子程序参数模式:
<强> my ( $mandatory_parameters, $optional_parameters ) = @_;
强>
如果每个模式中有几个,则此模式很有用。这种方法的优点是如果没有传递$optional_parameters
未定义,那么可以执行默认情况if ! $optional_parameters;
请注意,随后需要检查强制参数:
for ( qw/ a b c / ) {
die "Missing '$_' parameter\n"
unless exists $mandatory_parameters->{$_};
}
<强> my ( $parameters ) = @_;
强>
如果很少或没有强制参数,则很有用。
如果传递参数只是修改默认行为,那么它也非常有效。通过在包的范围内定义$default_parameters
,除非明确传递参数,否则默认值可以由后续的单行加载:
$parameters = { %$default_parameters, %$parameters };