我今天得到了这条奇怪的代码行,它告诉我'空'或'不空',具体取决于CWD是否有任何项目(.
和..
除外)。这个Perl是如何检查一个目录是否为空的工作?
我想知道它是如何工作的,因为它对我毫无意义。
perl -le 'print+(q=not =)[2==(()=<.* *>)].empty'
我感兴趣的是<.* *>
。我不明白它是如何得到目录中所有文件的名称。
我今天得到了这条奇怪的代码行,它告诉我'空'或'不空',具体取决于CWD是否有任何项目(.
和..
除外)。这个Perl是如何检查一个目录是否为空的工作?
我想知道它是如何工作的,因为它对我毫无意义。
perl -le 'print+(q=not =)[2==(()=<.* *>)].empty'
我感兴趣的是<.* *>
。我不明白它是如何得到目录中所有文件的名称。
这是一个高尔夫球单线。 -e
标志意味着执行命令行的其余部分作为程序。 -l
支持自动行结束处理。
<.* *>
部分是一个包含两种模式的glob:.*
和*
。
该部分
(q=not =)
是包含单一值的列表 - 字符串 “不”。 q=...=
是一个可替换的字符串分隔符,显然是因为单引号用于引用单行。
[...]
部分是该列表中的下标。标值将是0(值“不 ”)或1(无,打印为空字符串),根据该比较的结果:
2 == (()=<.* *>)
有很多发生在这里。比较测试glob是否返回了完全两个项目的列表(假设为.
和..
),但它是如何很棘手的。内部圆括号表示一个空列表。分配到此列表将glob放入列表上下文中,以便它返回目录中的所有文件。 (在标量上下文中,它将表现得像一个迭代器,一次只返回一个)。赋值本身在标量上下文中进行评估(位于比较的右侧),因此会返回分配的元素数量。
领先的+
是为了防止Perl解析列表作为参数到print
。尾部.empty
将字符串“empty”连接到列表中的任何字符串(即“not ”或空字符串)。
<.* *>
表示(glob(".*"), glob("*"))
。 glob
以与shell相同的方式扩展文件模式。
<.* *>
是由两个模式的水珠:.*
是与.
开始,*
对应于所有文件的所有文件名(这比通常的DOS/Windows约定不同)。
(()=<.* *>)
评估列表上下文中的glob,返回所有匹配的文件名。
然后,与2
的比较将其放入标量上下文中,以便将2
与返回的文件数进行比较。如果该号码是2
,则唯一的目录条目是.
和..
,句点。 ;-)
该功能的文档是here。 (滚动临近节结束)
我发现B::Deparse
模块帮助颇有几分破译一些东西,抛出了大多数程序员的眼睛,如q=...=
结构:
$ perl -MO=Deparse,-p,-q,-sC 2>/dev/null << EOF
> print+(q=not =)[2==(()=<.* *>)].empty
> EOF
use File::Glob();
print((('not ')[(2 == (() = glob('.* *')))] . 'empty'));
当然,这并不会立即产生“可读”的代码,但它肯定会转换一些绊脚石。
随意编辑更合适的标签 – dsm 2009-07-14 15:39:26
哈哈,你真是太好笑了!我在地板上大笑起来。你叫Perl线噪声!!!! HAHAHAHAHAHAHAHAHAHAHAHAHA! – jrockway 2009-07-14 15:50:45
好提交'年度混淆'。我喜欢Perl,但我更喜欢Perl代码中的注释。 – Boldewyn 2009-07-14 15:53:24