2013-05-13 90 views
1

Why would I use Perl anonymous subroutines instead of a named one?子程序/函数引用启发我思考的优点:匿名存储在数据结构

  • 存储在阵列中,哈希和标量匿名潜艇。

这是一个很酷的概念,但它在任何方面的实用吗?有什么理由不得不使用存储在某种数据结构中的匿名subs/sub引用?或者可能是一个方便的情况?

我明白为什么在某些情况下需要匿名subs,例如处理共享变量(当一个匿名sub在另一个sub内被声明时),但除非我遗漏了某些东西,我只是没有看到使用任何类型的函数引用。看起来我们应该直接调用这些函数,代码看起来会更好,更有组织。

请告诉我我错了。我很想有一个很好的理由来使用这些东西。

在此先感谢。 >能($方法)在概念上类似于,但更灵活和细节被隐藏 -

my %disp = (
    foo => sub { 'foo' }, 
    bar => sub { 'bar' }, 
); 

my $cmd = get_cmd_somehow(); 
if (defined $disp{$cmd}) { 
    $disp{$cmd}->(@args) 
} else { 
    die "I don't know how to handle $cmd" 
} 

(经由方法调度:

+1

查找调度表的概念。 http://en.wikipedia.org/wiki/Dispatch_table – DavidO 2013-05-13 23:49:06

+0

那么,符号表基本上是一个巨大的HoH(任意深度),并且它包含对每个命名子的引用。而这只是众多用途之一。 – ikegami 2013-05-13 23:56:20

+0

@ikegami一些语言是否也将它用于函数中的闭包,以便它们可以跟踪程序状态? – squiguy 2013-05-13 23:59:40

回答

2

面向对象的方法非常类似于匿名子例程。多态性意味着对象的方法可以改变,而调用代码不必手动查找以查看要运行的例程。这非常有用。

另外,想想perl的排序。为什么要为简单的排序方法设置一个命名的例程?同上映射和grep。

而且,迭代器非常有用。另外,考虑存储可以稍后解决的例程,而不是只能存储静态值。最后,如果你不想存储匿名例程(甚至是引用例程),那就是你的业务。但拥有这个选择比没有它好。

5

甲调度表用于动态地确定基于一些值要采取的步骤是有用)

匿名函数和词法关闭有许多其他用途;也许更深入地看“高阶函数”。 (例如,考虑map()/ grep()。)

+0

调度不是使用匿名子例程的解释。您可以使用正常的命名子例程实现相同的功能: my%disp =( foo => \&disp_foo, bar => \&disp_bar ); – msztolcman 2013-05-14 06:38:14

+0

这是真的 - 也解决了问题的第二部分,关于存储在数据结构中的子引用。 – 2013-05-14 11:56:17