2013-07-28 55 views
21

我不明白EXPORT_OKEXPORT的區別/使用情況。
大多數資源提到了線的東西:perl中的export vs export_ok

@Export允許模塊的功能和變量導出到使用標準的導入方法 用戶的命名空間。這樣,我們不需要 創建模塊訪問其成員的對象。
@EXPORT_OK根據需要爲符號(子例程和變量)的選擇性列表 輸出符號。

但我真的沒有看到這裏的區別/含義。
有人可以提供這兩個符號的區別/使用的一個小的基本例子嗎?

+0

如果有的話,你不應該導出許多符號。 @EXPORT通常會很小或爲空。 @EXPORT_OK可以包含更多。例如,Encode默認導出'encode'和'decode'('@ EXPORT'),但不是'is_utf8'('@ EXPORT_OK') – ikegami

回答

15

fine Exporter manual

  • use YourModule;
    這將導入所有的符號從YourModule的@EXPORT使用聲明的命名空間。
  • use YourModule();
    這會導致perl加載模塊,但不會導入任何符號。
  • use YourModule qw(...);
    此操作僅將調用者列出的符號導入其名稱空間。所有列出的符號必須在您的@EXPORT@EXPORT_OK中,否則會發生錯誤。 Exporter的高級導出功能可以像這樣訪問,但列表條目在語法上與符號名稱不同。

所以,如果你使用@EXPORT,有人做平常use YourModule;,那麼你只是污染了自己的一切,命名空間@EXPORT。但是,如果你使用@EXPORT_OK,他們必須特別要求輸入內容,以便使用你的模塊的人可以控制他們的命名空間會發生什麼。

不同的是真正的誰控制什麼進入了use的r命名空間的問題:如果你使用@EXPORT則模塊是use d確實,如果你使用@EXPORT_OK然後做進口的代碼控制自己的命名空間。

當然,你總是可以說use Whatever();保持不禮貌的模塊不會污染你的名字空間,但這很醜,你不應該圍繞想要在你的名字空間上塗寫的粗魯的代碼。

+0

所以'使用YourModule qw(ab);'和'@EXPORT qw(ab );'是沒有意義的?如果不是,那麼我仍然不明白爲什麼我們需要'@ EXPORT_OK' – Jim

+3

@Jim'我們的@ EXPORT'保存默認導出的符號(也就是'使用YourModule;')。這樣做被認爲是一種壞習慣*。 '@ EXPORT_OK'包含所有可以在明確請求下導出*的符號列表。 – amon

35

比方說,我有一個包MyPackage,它使用@EXPORT

#this is MyPackage.pm 
package MyPackage; 
@EXPORT = qw(do_awesome_thing); 

sub do_awesome_thing { ... } 

sub be_awesome { ... } 

現在,當我在我的代碼使用MyPackage

#this is myscript.pl 
use MyPackage; 

do_awesome_thing(); #works 

be_awesome(); #doesn't work 
MyPackage::be_awesome(); #works 

do_awesome_thing被自動導出到我的代碼MyPackage,沒有我說:「把這個給我。」 be_awesome未導出(並且它也不會與@EXPORT_OK一起導出,我只是將這一部分顯示爲讓您清楚「導出」給我們的內容)。

在另一方面,如果我有一個包MyOtherPackage使用@EXPORT_OK

#this is MyOtherPackage.pm 
package MyOtherPackage; 
@EXPORT_OK = qw(do_awesome_thing); 

sub do_awesome_thing { ... } 

sub be_awesome { ... } 

,然後嘗試

#this is mynewscript.pl 
use MyOtherPackage; 

do_awesome_thing(); #doesn't work 
MyOtherPackage::do_awesome_thing(); #works, as always 

直接調用do_awesome_thing線將無法正常工作。這是因爲把東西放在@EXPORT_OK中說:「只有在他們要求時才把這個給我的用戶」。由於我們剛纔說use MyOtherPackage沒有明確要求在此處導入do_awesome_thing,因此它不會被導入,並且只能通過指定包名來訪問。

您要求導入do_awesome_thing的方式是在上面的第二行mynewscript.pl中說use MyOtherPackage qw(do_awesome_thing)。這說直接提供模塊並使do_awesome_thing可用。之後,上述mynewscript.pl中的第四行將開始工作。用戶可以與第一包指定use MyPackage qw(do_awesome_thing)也,而在這種情況下,任何在@EXPORT列表其他

注意將不能出口,只能do_awesome_thing會。因此,除了默認情況下use PackageName;@EXPORT@EXPORT_OK表現相似。在默認情況下,@EXPORT中的任何內容都會自動拋入用戶的腳本中,而@EXPORT_OK更有禮貌,並且不會導出任何內容。

+4

*使用@EXPORT,你只有兩個選擇* ...錯誤;錯了。 '@ EXPORT'和'@ EXPORT_OK'的工作大體相同:無論哪種情況,用戶都可以指定他們希望導入的名稱列表。它們*僅*在用戶提供時會發生什麼不同*沒有要導入的名稱列表* - 在這種情況下,'@ EXPORT'上的內容被導出,而'@ EXPORT_OK'上的內容不是。 – tobyink

+1

@tobyink謝謝,還沒有與EXPORT合作過,所以我不知道,現在我改變了這個部分。當谷歌搜索來證實這一點時,我遇到了這本O'Reilly的書(http://docstore.mik.ua/orelly/perl/advprog/ch06_05.htm),它似乎犯了同樣的錯誤:「如果模塊使用EXPORT而不是EXPORT_OK,用戶將獲得所有導出的符號,而不管它們是否在導入列表中提及。「 但我已經測試了這種行爲,並確認你是正確的,書中(顯然)是錯誤的。 – sundar