检查目录是否为空的 Perl 一个衬垫是如何工作的?
我今天收到了这行奇怪的代码,它告诉我“空”或“非空”,具体取决于 CWD 是否有任何项目(.
和 ..
除外)在里面。
我想知道它是如何工作的,因为它对我来说毫无意义。
perl -le 'print+(q=not =)[2==(()=<.* *>)].empty'
我感兴趣的是 <.* *>
。 我不明白它如何获取目录中所有文件的名称。
I got this strange line of code today, it tells me 'empty' or 'not empty' depending on whether the CWD has any items (other than .
and ..
) in it.
I want to know how it works because it makes no sense to me.
perl -le 'print+(q=not =)[2==(()=<.* *>)].empty'
The bit I am interested in is <.* *>
. I don't understand how it gets the names of all the files in the directory.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是一款打高尔夫球的单线球。
-e
标志意味着将命令行的其余部分作为程序执行。-l
启用自动行结束处理。<.* *>
部分是一个包含两个要扩展的模式的 glob:.*
和*
。这部分
是一个包含单个值的列表——字符串“not”。
q=...=
是一种备用字符串分隔符,显然使用它是因为单引号用于引用单行符。[...]
部分是该列表的下标。 下标的值将是 0(值“not”)或 1(什么都没有,打印为空字符串),具体取决于比较的结果:这里发生了很多事情。 比较测试 glob 是否返回恰好包含两个项目的列表(假设为
.
和..
),但它如何做到这一点很棘手。 里面的括号表示一个空列表。 分配给此列表会将 glob 放入列表上下文中,以便它返回目录中的所有文件。 (在标量上下文中,它的行为类似于迭代器,一次仅返回一个。)赋值本身在标量上下文中求值(位于比较的右侧),因此返回分配的元素数。前导的
+
是为了防止 Perl 将列表解析为print
的参数。 尾随的.empty
将字符串“empty”连接到列表中的任何内容(即“not ”或空字符串)。It's a golfed one-liner. The
-e
flag means to execute the rest of the command line as the program. The-l
enables automatic line-end processing.The
<.* *>
portion is a glob containing two patterns to expand:.*
and*
.This portion
is a list containing a single value -- the string "not". The
q=...=
is an alternate string delimiter, apparently used because the single-quote is being used to quote the one-liner.The
[...]
portion is the subscript into that list. The value of the subscript will be either 0 (the value "not ") or 1 (nothing, which prints as the empty string) depending on the result of this comparison:There's a lot happening here. The comparison tests whether or not the glob returned a list of exactly two items (assumed to be
.
and..
) but how it does that is tricky. The inner parentheses denote an empty list. Assigning to this list puts the glob in list context so that it returns all the files in the directory. (In scalar context it would behave like an iterator and return only one at a time.) The assignment itself is evaluated in scalar context (being on the right hand side of the comparison) and therefore returns the number of elements assigned.The leading
+
is to prevent Perl from parsing the list as arguments toprint
. The trailing.empty
concatenates the string "empty" to whatever came out of the list (i.e. either "not " or the empty string).是一个由两种模式组成的 glob:
.*
是所有以.
开头的文件名,而*
对应于所有文件(这与通常的 DOS/Windows 约定)。评估列表上下文中的 glob,返回所有匹配的文件名。
然后,与
2
的比较将其放入标量上下文中,以便将2
与返回的文件数进行比较。 如果该数字是2
,则唯一的目录条目是.
和..
,句点。 ;-)is a glob consisting of two patterns:
.*
are all file names that start with.
and*
corresponds to all files (this is different than the usual DOS/Windows conventions).evaluates the glob in list context, returning all the file names that match.
Then, the comparison with
2
puts it into scalar context so2
is compared to the number of files returned. If that number is2
, then the only directory entries are.
and..
, period. ;-)<.* *>
表示(glob(".*"), glob("*"))
。glob
以与 shell 相同的方式扩展文件模式。<.* *>
means(glob(".*"), glob("*"))
.glob
expands file patterns the same way the shell does.我发现
B::Deparse
模块对于破译一些让大多数程序员望而却步的东西有很大帮助,例如q=...=
构造:当然,这不会立即产生“可读”代码,但它肯定会转换一些绊脚石。
I find that the
B::Deparse
module helps quite a bit in deciphering some stuff that throws off most programmers' eyes, such as theq=...=
construct:Of course, this doesn't instantly produce "readable" code, but it surely converts some of the stumbling blocks.
该功能的文档位于此处。 (滚动到该部分末尾附近)
The documentation for that feature is here. (Scroll near the end of the section)