在Perl中,为什么'while(<;HANDLE>;){…}'构造没有本地化`$\`?
Perl没有使用以下语法自动本地化在Perl中,为什么'while(<;HANDLE>;){…}'构造没有本地化`$\`?,perl,language-design,while-loop,local,Perl,Language Design,While Loop,Local,Perl没有使用以下语法自动本地化$\uuuu的设计(或技术)原因是什么: while (<HANDLE>) {...} 我的猜测是,它与在命令行开关的“Super-AWK”模式下使用Perl有关,但这可能是错误的 因此,如果有人知道(或者更好地说是参与了语言设计的讨论),你能和我们分享一下这种行为背后的原因吗?更具体地说,为什么允许$\ucode>的值在循环之外保持被认为是重要的,尽管它可能会导致错误(我倾向于在SO和其他Perl代码中到处都能看到) 如果从上面看不清楚,$\u
$\uuuu
的设计(或技术)原因是什么:
while (<HANDLE>) {...}
我的猜测是,它与在命令行开关的“Super-AWK”模式下使用Perl有关,但这可能是错误的
因此,如果有人知道(或者更好地说是参与了语言设计的讨论),你能和我们分享一下这种行为背后的原因吗?更具体地说,为什么允许$\ucode>的值在循环之外保持被认为是重要的,尽管它可能会导致错误(我倾向于在SO和其他Perl代码中到处都能看到)
如果从上面看不清楚,$\uu
必须使用进行本地化,而的原因在此示例中显示:
sub read_handle {
while (<HANDLE>) { ... }
}
for (1 .. 10) {
print "$_: \n"; # works, prints a number from 1 .. 10
read_handle;
print "done with $_\n"; # does not work, prints the last line read from
# HANDLE or undef if the file was finished
}
sub-read\u句柄{
而(){…}
}
对于(1..10){
打印“$\ \ \ n”\工作,打印1到10之间的数字
读写手柄;
打印“使用$\n完成”;#不起作用,打印从中读取的最后一行
#如果文件已完成,则为HANDLE或undef
}
来自perlmonks.org网站:
foreach
而
,因为它们是两个整体
不同的事情<代码>foreach
始终
循环时指定给变量
在列表上,而在正常情况下
不。只是while()
是
一个例外,只有在
单钻石操作员有一个
对$的隐式赋值
而且:
为什么while()
不会隐式地将$本地化为
它的神奇之处在于有时
您希望访问的最后一个值
$\
在循环之外
很简单,而
从不本地化。没有变量与while
构造相关联,因此它甚至没有任何要本地化的内容
如果您更改while
循环表达式或while
循环体中的某个变量,则您有责任对其进行适当的范围限定。推测:因为for
和foreach
是迭代器和循环覆盖值,而while
在一定条件下运行。在while()
的情况下,条件是从文件中读取数据。
是写入$\uu
的内容,而不是while
。隐式defined()
测试只是一种启示,可以防止原始代码在读取假值时终止循环
对于其他形式的while
循环,例如while(/foo/)
您不想本地化$\uuuu
虽然我同意如果While()
本地化$\uuuz
会很好,但这必须是一个非常特殊的情况,这可能会导致识别何时触发和何时不触发的其他问题,就像
区分句柄读取或调用glob
作为旁注的规则一样,我们只编写while()
,因为Perl没有真正的迭代器。如果Perl有合适的迭代器,
将返回一个迭代器for
将使用它一次迭代一行,而不是将整个文件拖入数组。没有必要使用while()
或与之相关的特殊情况。这就是为什么我(几乎)从不信任$。我想你的意思是{local$;而(){…}@MkV=>上面只是一个代码片段(因此,..
,没有定义句柄
,等等)。如果你因为这个问题而否决了这个问题,那么周围的范围就被暗示了(不管是一个裸块、一个子例程的块、一个控制语句的块……),这很可悲。所需行为的解决方法:for(local$\u=;defined;$\u=)…
More Perlistic:while(defined(local$\u=){…}
对于和
,这是这个问题的关键,但是,为什么这个行为被认为足够重要,足以证明它可能导致的错误。就我个人而言,我从来没有需要$
的值来保持循环之外的状态,但偶尔会忘记本地$
。没有变量与while
构造相关联,但肯定有一个变量与while()
构造相关联。我认为这就像调整窥视孔优化器一样简单,该优化器重写while()
以生成{local$\uuu;while(defined($\u=){…}}
@Eric Strom,我想不出该解决方案有任何问题——它不会破坏范围,next/last/redo或异常——但我认为这需要一些主要的更改,以允许优化程序区分while()
(应该本地化)和while(定义($)
(不应该)。
local $_;
while (<HANDLE>) {...}
sub read_handle {
while (<HANDLE>) { ... }
}
for (1 .. 10) {
print "$_: \n"; # works, prints a number from 1 .. 10
read_handle;
print "done with $_\n"; # does not work, prints the last line read from
# HANDLE or undef if the file was finished
}