当没有给出参数列表时,map
是否有充分理由不从@_
(在函数中)或@ARGV
(在其他任何地方)读取?
答案 0 :(得分:8)
我不能说为什么Larry没有map
,grep
而其他列表函数在@_
上运行pop
和shift
,但我可以告诉你为什么我不愿意。默认变量过去很流行,但Perl程序员发现大多数“默认”行为导致的问题多于他们解决的问题。我怀疑他们今天会把它变成语言。
第一个问题是记住传递无参数时函数的作用。它是否作用于隐藏变量?哪一个?你只需要死记硬背,这使得学习,阅读和编写语言的工作量大大增加。你可能会弄错它,这意味着错误。这可以通过Perl对它的一致性来缓解(即所有使列表操作的函数在@_和所有函数上运行,这些函数使得标量在$ _上运行)但是存在更多问题。
第二个问题是基于上下文的行为更改。在子程序之外取一些代码,或将其放入子程序中,突然它的工作方式不同。这使得重构变得更难。如果您将其设为 @_
或 @ARGV
,则此问题就会消失。
第三,默认变量有被悄悄修改和阅读的倾向。 $_
因为这个原因很危险,你永远不知道什么时候会覆盖它。如果采用@_
作为默认列表变量,则此行为可能会泄漏。
第四,它可能会导致复杂的语法问题。我认为这是保持它不被添加到语言中的原始原因之一,当$_
流行时。
第五,当您编写主要与@ARGV
一起使用的脚本时,@ARGV
作为默认值是有意义的...但是在处理库时没有任何意义。 Perl程序员已经从编写快速脚本转向编写库。
第六,使用$_
作为默认值是一种将标量操作链接在一起而不必反复写入变量的方法。如果Perl对其返回值更加一致,并且如果正则表达式没有特殊语法,那么这可能已经减轻了,但是你有它。列表已经可以链接map { ... } sort { ... } grep /.../, @foo
,因此用例由更有效的机制处理。
最后,它的使用非常有限。您希望将@_
传递给map
和grep
的情况非常罕见。隐藏默认值的问题远远大于避免键入两个字符。当Perl主要用于快速和肮脏的工作时,这种空间节省可能略微更有意义,但是在编写超出几页代码的任何内容时没有任何意义。
PS shift
默认为@_
已在my $self = shift
找到了一个利基,但我发现这只会让人眼前一亮,因为Perl的论证处理非常糟糕。
答案 1 :(得分:2)
map
函数接受列表,而不是数组。 shift
采用数组。另一方面,对于列表,@_
/ @ARGV
可能是也可能不是公平默认值。