2014-04-14 49 views
6

我在看一些代碼,但我不明白下面一行是做/檢查:這行代表perl中的含義是什麼?

return if !%Foo::Details:: ; 

究竟這是什麼做的?它檢查模塊Foo :: Details的存在嗎?

+3

看起來像一個非常糟糕的方式來測試模塊是否已被加載到符號表中。 '%Foo :: Details'是包'Foo :: Details'的符號表項,如果未加載,它將返回false,否則返回true。看看['perlmod'的符號表部分](http://perldoc.perl.org/perlmod.html#Symbol-Tables) –

+0

@HunterMcMillen我認爲它很高雅,完全基於它的緊湊性。究竟是什麼使它變窮? – Jarmund

+1

這段代碼在做什麼並不是很清楚,這就是爲什麼我認爲它很糟糕。有更好,更可讀的解決方案。 –

回答

9

標量上下文中的散列值如果爲空,則返回false,因此如果散列值%Foo::Details::爲空,則代碼將返回空列表。

該散列是Foo::Details命名空間的符號表。如果在Foo::Details命名空間中創建了包變量或子包,則將在%Foo::Details::中創建與該變量或子名稱相對應的glob。因此,如果Foo :: Details命名空間爲空,它將返回一個空列表。

$ cat >Foo/Details.pm 
package Foo::Details; 
sub boo { } 
1; 

$ perl -E'say %Foo::Details:: ?1:0;' 
0 

$ perl -E'use Foo::Details; say %Foo::Details:: ?1:0;' 
1 

它可能試圖檢查Foo :: Details模塊是否已加載,但它不完美。例如,即使只加載了Foo :: Details :: Bar,它也會認爲Foo :: Details已被加載。要檢查Foo :: Details是否已加載,最好檢查$INC{"Foo/Details.pm"}是否爲真。這種方法的問題是它不會找到「內聯模塊」。

3

此代碼測試是否已加載模塊。 %Foo::Details::是模塊Foo::Details的符號表。

如果Foo::Details從未加載%Foo::Details::將返回false(因爲它不包含任何元素),當其與!否定將返回true,並從你在任何函數返回。

你可以閱讀更多關於符號表中perlmod#Symbol Tables

此外,here is another SO post談論如何確定模塊是否已加載。

+0

更正確的說%Foo :: Details :: * is *模塊的符號表 – ysth

+0

第二段是錯誤的。看到我的答案。 – ikegami

+0

技術上它不是一個條目嗎?由於它在'%main ::'中被保存? –