2009-07-14 119 views
5

我今天得到了這條奇怪的代碼行,它告訴我'空'或'不空',具體取決於CWD是否有任何項目(...除外)。這個Perl是如何檢查一個目錄是否爲空的工作?

我想知道它是如何工作的,因爲它對我毫無意義。

perl -le 'print+(q=not =)[2==(()=<.* *>)].empty' 

我感興趣的是<.* *>。我不明白它是如何得到目錄中所有文件的名稱。

+0

隨意編輯更合適的標籤 – dsm 2009-07-14 15:39:26

+3

哈哈,你真是太好笑了!我在地板上大笑起來。你叫Perl線噪聲!!!! HAHAHAHAHAHAHAHAHAHAHAHAHA! – jrockway 2009-07-14 15:50:45

+0

好提交'年度混淆'。我喜歡Perl,但我更喜歡Perl代碼中的註釋。 – Boldewyn 2009-07-14 15:53:24

回答

16

這是一個高爾夫球單線。 -e標誌意味着執行命令行的其餘部分作爲程序。 -l支持自動行結束處理。

<.* *>部分是一個包含兩種模式的glob:.**

該部分

(q=not =) 

是包含單一值的列表 - 字符串 「不」。 q=...=是一個可替換的字符串分隔符,顯然是因爲單引號用於引用單行。

[...]部分是該列表中的下標。標值將是0(值「不 」)或1(無,打印爲空字符串),根據該比較的結果:

2 == (()=<.* *>) 

有很多發生在這裏。比較測試glob是否返回了完全兩個項目的列表(假設爲...),但它是如何很棘手的。內部圓括號表示一個空列表。分配到此列表將glob放入列表上下文中,以便它返回目錄中的所有文件。 (在標量上下文中,它將表現得像一個迭代器,一次只返回一個)。賦值本身在標量上下文中進行評估(位於比較的右側),因此會返回分配的元素數量。

領先的+是爲了防止Perl解析列表作爲參數到print。尾部.empty將字符串「empty」連接到列表中的任何字符串(即「not  」或空字符串)。

3

<.* *>表示(glob(".*"), glob("*"))glob以與shell相同的方式擴展文件模式。

7
<.* *> 

是由兩個模式的水珠:.*是與.開始,*對應於所有文件的所有文件名(這比通常的DOS/Windows約定不同)。

(()=<.* *>) 

評估列表上下文中的glob,返回所有匹配的文件名。

然後,與2的比較將其放入標量上下文中,以便將2與返回的文件數進行比較。如果該號碼是2,則唯一的目錄條目是...,句點。 ;-)

0

該功能的文檔是here。 (滾動臨近節結束)

2

我發現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')); 

當然,這並不會立即產生「可讀」的代碼,但它肯定會轉換一些絆腳石。