sid*_*yll 3 perl filehandle while-loop
在阅读有关高级Perl编程(1)的书时,我遇到了这段代码:
while (defined($s = <>)) {
...
Run Code Online (Sandbox Code Playgroud)
defined在这里使用有什么特别的理由吗?perlop的 文档
说:
在这些循环结构中,然后测试指定的值(无论是自动还是显式赋值)以查看它是否已定义.定义的测试避免了line具有字符串值的问题,该字符串值将被Perl视为false,例如a
""或"0"没有尾随换行符.如果你真的想要这些值来终止循环,那么它们应该被明确地测试:[...]
那么,是否会有一个角落案例,或者仅仅是因为这本书太旧而且defined在最近的Perl版本中添加了自动测试?
(1) 高级Perl编程,第一版,Sriram Srinivasan.奥莱利(1997)
Perl有很多隐式行为,比大多数其他语言都多.Perl的座右铭是不止一个人去做,并且因为有太多的隐含行为,通常有多种方式表达完全相同的东西.
/foo/代替$_ =~ m/foo/
$x = shift代替$x = shift @_
while (defined($_=<ARGV>))代替while(<>)等等
使用哪种表达方式主要取决于您当地的编码标准和个人偏好.更明确的表达提醒读者在幕后真正发生了什么.这可能会也可能不会提高代码的可读性 - 这取决于受众的知识水平以及您是否使用了众所周知的习语.
在这种情况下,隐式行为比看起来要复杂一些.有时perl会隐式地defined(...)对readline运算符的结果执行测试:
$ perl -MO=Deparse -e 'while($s=<>) { print $s }'
while (defined($s = <ARGV>)) {
print $s;
}
-e syntax OK
Run Code Online (Sandbox Code Playgroud)
但有时它不会:
$ perl -MO=Deparse -e 'if($s=<>) { print $s }'
if ($s = <ARGV>) {
print $s;
}
-e syntax OK
$ perl -MO=Deparse -e 'while(some_condition() && ($s=<>)) { print $s }'
while (some_condition() and $s = <ARGV>) {
print $s;
}
-e syntax OK
Run Code Online (Sandbox Code Playgroud)
假设您担心此隐式行为应该处理的极端情况.您是否已经承诺perlop了内存以便了解Perl何时使用此隐式行为以及何时不使用?您是否了解Perl v5.14与Perl v5.6之间在此行为上的差异?阅读代码的人会理解吗?
同样,关于何时使用更明确的表达式没有正确或错误的答案,但是当隐式行为更深奥时,使用显式表达式的情况更强.