看起来很简单的一段代码肯定没有做我想做的事情。
有人可以向我解释它的作用和原因吗?
my $dir = './some/directory';
if ( -d $dir && <$dir/*> ) {
print "Dir exists and has non-hidden files in it\n";
}
else {
print "Dir either does not exist or has no non-hidden files in it\n";
}
在我的测试用例中,目录确实存在且为空。但是,then
的{{1}}(第一)部分已按预期触发,而不是if
部分。
我不需要任何人建议如何完成我想要完成的任务。我只想了解Perl对此代码的解释,这绝对不符合我的。
答案 0 :(得分:4)
在标量上下文中使用glob
(又名<filepattern>
)使其成为迭代器;它将在每次调用时一次返回一个文件,并且在完成对初始结果的迭代之前不会响应模式中的更改(例如,不同的$ dir);我怀疑这会导致你看到麻烦。
简单的答案是始终在列表上下文中使用它,如下所示:
if( -d $dir && ( () = <$dir/*> ) ) {
如果你绝对确定你会在尝试开始新的迭代之前耗尽迭代器,那么<p> glob可能只能在代码中的标量上下文中安全地使用。大多数情况下,在标量上下文中完全避免使用glob更容易。
答案 1 :(得分:1)
我认为@ysth
处于正确的轨道,但在标量上下文中重复调用glob
不会产生误报。
例如
use strict;
use warnings;
use 5.010;
say scalar glob('/usr/*'), "\n";
say scalar glob('/usr/*'), "\n";
<强>输出强>
/usr/bin
/usr/bin
但是 是什么 任何单个调用到glob
维持一个状态,所以如果我有
use strict;
use warnings;
use 5.010;
for my $dir ( '/sys', '/usr', '/sys', '/usr' ) {
say scalar glob("$dir/*"), "\n";
}
<强>输出强>
/sys/block
/sys/bus
/sys/class
/sys/dev
很明显,循环中的glob
语句维持状态,忽略对$dir
的更改。
这类似于pos
(和相应的\G
正则表达式锚点)具有每个标量变量的状态的方式,以及没有特定文件句柄的print
如何打印到< em>最后选择的句柄。最后,它是所有Perl的工作方式, it 变量$_
是最终的例子。