为什么我要使用 Perl 匿名子例程而不是命名子例程?
我只是好奇为什么人们会选择在 Perl 中使用匿名子例程而不是命名子例程。 谢谢。
I'm just curious why one would choose to use an anonymous subroutine, versus a named one, in Perl. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
最后一点可能是最重要的,因为它通常是 Perl 中命名子例程与匿名子例程最意想不到的方面。 示例:
但是将“内部”从命名子例程更改为对匿名子例程的引用,它的工作方式就不那么令人惊讶了:(
当然,每个人的期望都不同,因此“预期”周围的“恐吓引号”。)
这是实际代码中的使用示例(尽管应该注意的是,
File::Find
接口通常被认为是一个很差的接口,因为它使用了全局变量,而不是使用了匿名子例程) :将命名子例程作为
wanted
参数的值传递将需要使用只能使用一次的例程污染命名空间,并在内定义命名子例程>find_files()
子例程将表现出前面演示的“意外”行为。The last point is probably the most important, because it's often the most unexpected facet of named vs. anonymous subroutines in Perl. Example:
But change "inner" from a named subroutine to a reference to an anonymous subroutine and it works is a much less surprising manner:
(Of course, everyone's expectations are different, thus the "scare quotes" around "expected.")
Here's an example use in real code (though it should be noted that the
File::Find
interface is generally considered to be a poor one—due to its use of global variables, not its use of anonymous subroutines):Passing a named subroutine as the value of the
wanted
parameter would require polluting the namespace with a routine that may only be used once, and defining a named subroutine within thefind_files()
subroutine would exhibit the "unexpected" behavior demonstrated earlier.我想到了回调和生成器。 一个例子:
Callbacks and generators come to mind. An example:
“匿名”子例程与常规的命名子例程非常相似,只是它们不绑定到符号表中的名称。
在第二种情况下,创建“匿名”子例程,然后将其绑定到当前命名空间中的名称“Foo”。 BEGIN 块使其在编译时发生,就像处理命名子例程一样。 (这有点复杂,因为第一种情况给它一个将显示在堆栈跟踪中的名称。)
每当您想在运行时创建函数时,匿名子例程都很有用。 这对于“闭包”特别有用——“记住”其词法上下文的函数。 例如,将列表转换为迭代器:
有关为什么匿名子例程有用的更多信息,我推荐这本书 Higher Order Perl 描述了 Perl 中函数式编程的各种技术和应用。
"Anonymous" subroutines are really similar to regular, named subroutines except that they aren't bound to a name in the symbol table.
In the second case, the "anonymous" subroutine is created and then bound to the name "Foo" in the current namespace. The BEGIN block makes it happen at compile time, just like how a named subroutine is treated. (It's a little more complicated in that the first case gives it a name that will show up in a stack trace.)
Anonymous subroutines are useful any time you want to create a function at run-time. This is particularly good for "closures" -- functions that "remember" their lexical context. For example, turning a list into an iterator:
For a lot more on why anonymous subroutines are useful, I recommend the book Higher Order Perl which describes various techniques and applications of functional programming in Perl.
我在掌握 Perl 中讨论了匿名子例程以及为什么要使用它们。 简而言之,您开始将行为视为另一种形式的数据,就像您考虑字符串或数字一样。 当您对这个想法感到满意时,您可以做一些非常令人惊奇的事情,因为您可以将许多决策推迟到程序的最后阶段,并且您不必扭曲代码设计来提前处理每种情况可能会出现。
您可以在知道要运行子例程的情况下编写代码,只是您还不知道是哪个子例程。 您相信前面的步骤可以为您解决这个问题。 一旦你能做到这一点,你就进入了编程的另一个层次,感觉就像你正在编写代码来为你创建程序一样。 通过这种方式,一些编程问题变得更容易解决。
而且,与其他所有功能一样,您可能会过度使用它或使用不当。
I talk about anonymous subroutines and why you would use them in Mastering Perl. In short, you start thinking about behavior as just another form of data just like you think about strings or numbers. When you are comfortable with that idea, you can do some pretty amazing things because you can push off a lot of decisions to very late in the program and you don't have to contort your code design to deal ahead of time with every situation that might show up.
You can write code knowing that you are going to run a subroutine, only you don't know which one yet. You trust the previous steps to work that out for you. Once you can do that, you're on another level of programming that feels like you're writing code to create your program for you. Some programming problems become much easier to solve this way.
And, like every other feature, you can take this too far or use it inappropriately.
匿名子例程的规范答案通常是数组的数字排序:
{ $a <=>; $b }
代表匿名子例程。The canonical answer for anonymous subroutine is usually the numeric sorting of an array :
The
{ $a <=> $b }
represents an anonymous subroutine.第一:子事物就是子事物。 my $thing=sub... 是存储在变量中的子引用。
第二:有一个微妙的用法差异:
将 [
sub yy
...] 更改为 [my $yy = sub {
...] 或 [local *yy = sub{
...] 并且投诉消失了。另外,说实话,对 subs 的引用更容易处理,就像 @x=(1,2,3) 与 $x=[1, 2, 3] 一样。
First: sub thing is a sub. my $thing=sub... is a sub reference stored in a variable.
Second: There's a subtle usage difference:
Change [
sub yy
...] to [my $yy = sub {
...] or [local *yy = sub{
...] and the complaint goes away.Also, to be honest, references-to-subs are just easier to deal with, much the same as @x=(1,2,3) versus $x=[1, 2, 3].
这是我的 重写的示例Nasm's version.pl
基本上我能想到的唯一原因是为了回调,或者为了跳转表。
Here's an example from my rewrite of Nasm's version.pl
Basically the only reason I can think of is for calbacks, or for a jump table.