没有$或@的Perl中的_(单下划线)是什么?

Kim*_*Kim 46 perl

我有一些像这样的代码:

if (!-d _ || !-o _ || ($vncUserDirUnderTmp && ($mode & 0777) != 0700)) {
    raise Exception("$prog: Wrong type or access mode of $vncUserDir.\n")
}
Run Code Online (Sandbox Code Playgroud)

我可以在Perl中找到有关的信息@_,$_但不能_单独查找.它在这里-d _-o _这里意味着什么?

zdi*_*dim 58

filetest(-X)运算符一起使用时stat,将使用先前文件测试的结构

如果任何文件测试(或其中之一statlstat运营商)被赋予特殊的文件句柄由一个孤立的下划线,那么stat以前的文件测试(或结构stat运营商)使用,节省了系统调用.
......
示例:

stat($filename);  
print "Readable\n" if -r _;  
print "Writable\n" if -w _;
...
Run Code Online (Sandbox Code Playgroud)

因此在您的示例中!-d _测试文件last stat-ed是否不是目录.

更新  

不寻常的_是一个typeglob *_但是运营商期望文件句柄*可以省略,就像<*STDIN>可以写成<STDIN>.它位于符号表中

print *{$main::{_}}{IO}, "\n";   # -->  IO::Handle=IO(0x2311970)
Run Code Online (Sandbox Code Playgroud)

在单行中*_,只有在调用stat和创建后才能设置_.


Dav*_*oss 40

当你调用文件测试的运营商之一(-f,-d,-s等)的Perl实际上使操作系统的调用stat函数.该stat函数返回一个结构,其中包含有关该文件的各种有趣信息,但每个文件测试操作符只查看该结构中的一个字段(它是一个文件吗?它是一个目录吗?它有多大?)

通常你可能想知道更多关于文件的一条信息(它是一个文件吗?我可以读它吗?我可以执行它吗?)写这个的天真的方法是:

if (-f $file and -r $file and -x $file)
Run Code Online (Sandbox Code Playgroud)

但这会产生三次调用stat- 每次调用只会查看结构中的一个字段.为了缓解这种情况,Perl很聪明并且缓存了最近一次调用的结果stat.它是针对特殊文件句柄缓存的_.因此,编写相同代码的更有效方法是:

if (-f $file and -r _ and -x _)
Run Code Online (Sandbox Code Playgroud)

这只能拨打一个电话stat.

从Perl 5.10开始,您还可以使用"堆叠文件测试"并将此代码编写为:

if (-x -r -f $file) # Note reversed order of operators
Run Code Online (Sandbox Code Playgroud)

更新: perldoc说这是关于堆叠文件操作符的.

从Perl 5.10.0开始,作为纯语法糖的一种形式,您可以以-f -w -x $file相当于的方式堆栈文件测试操作符"-x $file && -w _ && -f _.(这只是一种奇特的语法:如果你使用返回值-f $file作为另一个filetest运算符的参数,就不会发生特殊的魔法.)

  • 我今天学了些新东西!(不知道可堆叠文件测试.) (8认同)
  • 它们实际上是排队的(从左到右执行),对吧? (2认同)