我今天得到了這條奇怪的代碼行,它告訴我'空'或'不空',具體取決於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