【发布时间】:2011-05-23 17:59:21
【问题描述】:
我有一组如下所示的子例程:
sub foo_1($) {
my $name = shift;
my $f;
run_something();
open($f, $name) or die ("Couldn't open $name");
while (<$f>) {
//Something for foo_1()
}
close($f);
do_something_else();
}
我有四个或更多看起来相同的东西,唯一改变的是 while 块的主体。我想对此进行抽象并停止复制粘贴代码。
- 有没有办法编写一个接受代码块并执行它的子例程?
为了提供更多上下文,不同的 foo 子例程是不同的有限状态机 (FSM),它读取不同文件的内容并将数据提供给哈希引用。也许有比我想要完成的更聪明的事情去做。
【问题讨论】:
-
一般来说,函数原型不是必需的,我觉得它们有点用处。
-
@jiggy 你能详细说明一下吗?
-
=> 在这种情况下,使用
($)原型可能并不像您认为的那样。它确实意味着“给我一个论点”,但它也意味着“对该论点施加标量上下文”。因此,如果您有一个包含一个元素的数组,并称为foo_1 @array,那么foo_1将传递数字1,这是数组中元素的计数。要真正获得第一个参数,您需要将其称为foo_1 $array[0]。如果您没有原型,那么您可以将其称为foo_1 @array,它会正常工作。 -
... 一些 Perl 程序员将这种上下文强制称为“远距离动作”,因为函数调用本身并没有告诉您参数将在标量上下文中(这可能是难以找到错误的来源)。通常,您应该将 Perl 中的原型使用限制在您想要编写像内置函数一样解析的函数的时候(例如在我下面的回答中)。参数验证可以在运行时在子例程顶部使用类似
@_ == 1 or die "function takes 1 argument"的行来完成。 -
@Eric 好!我真的想对 foo_1 的参数强加一个“标量上下文”(如示例中唯一的 arg 是文件名),但我并不完全了解“仅用于内置函数之类的函数”部分。谢谢。
标签: perl arguments subroutine