2013-07-28 10 views
21

मुझे समझ में नहीं आता कि EXPORT_OK बनाम EXPORT का अंतर/उपयोग केस क्या है।निर्यात बनाम export_ok perl

@Export उपयोगकर्ता के नाम स्थान मानक आयात विधि का उपयोग करने के लिए कार्य करता है और मॉड्यूल की चर निर्यात करने के लिए अनुमति देता है:
अधिकांश संसाधनों की लाइनों में कुछ का उल्लेख है। इस तरह, हम को अपने सदस्यों तक पहुंचने के लिए मॉड्यूल के लिए ऑब्जेक्ट्स बनाने की आवश्यकता नहीं है।
@EXPORT_OK मॉड्यूल के प्रतीकों (सबराउटिन और चर) के चुनिंदा सूची के लिए मांग आधार पर प्रतीकों का निर्यात करता है।

लेकिन मुझे वास्तव में अंतर/अर्थ दिखाई नहीं देता है।
क्या कोई इन 2 प्रतीकों के अंतर/उपयोग का एक छोटा मौलिक उदाहरण प्रदान कर सकता है?

+0

यदि आपको कोई भी डिफ़ॉल्ट रूप से कई प्रतीकों को निर्यात नहीं करना चाहिए। @EXPORT आमतौर पर छोटा या खाली होगा। @EXPORT_OK और भी शामिल हो सकता है। उदाहरण के लिए, एनकोड निर्यात 'एनकोड' और 'डीकोड' डिफ़ॉल्ट रूप से (' @ निर्यात'), लेकिन 'is_utf8' (' @ EXPORT_OK') नहीं – ikegami

उत्तर

15

fine Exporter manual से:

  • use YourModule;
    यह उपयोग बयान की नेम स्पेस में YourModule के @EXPORT से सभी प्रतीकों आयात करता है।
  • use YourModule();
    यह आपके मॉड्यूल को लोड करने के लिए perl का कारण बनता है लेकिन कोई प्रतीक आयात नहीं करता है।
  • use YourModule qw(...);
    यह केवल कॉलर द्वारा उनके नामस्थान में सूचीबद्ध प्रतीक आयात करता है। सभी सूचीबद्ध प्रतीकों को आपके @EXPORT या @EXPORT_OK में होना चाहिए, अन्यथा कोई त्रुटि होती है। निर्यातक की उन्नत निर्यात सुविधाओं को इस तरह एक्सेस किया जाता है, लेकिन सूची प्रविष्टियों के साथ जो प्रतीकात्मक रूप से प्रतीक नामों से अलग होते हैं।

इसलिए, यदि आप @EXPORT का उपयोग करें और किसी को हमेशा की तरह use YourModule; करता है, तो आप सब कुछ के साथ उनके नाम स्थान @EXPORT में प्रदूषित कर दिया है। लेकिन, यदि आप @EXPORT_OK का उपयोग करते हैं, तो उन्हें विशेष रूप से चीजों को आयात करने के लिए कहा जाना चाहिए ताकि आपके मॉड्यूल का उपयोग करने वाले व्यक्ति पर उनके नामस्थान के साथ क्या हो।

अंतर वास्तव में कौन क्या use आर के नाम स्थान में हो जाता है को नियंत्रित करता है की बात है: यदि आप @EXPORT तो का उपयोग करता है, मॉड्यूल जा रहा है use घ अगर आप @EXPORT_OK तो कोड आयात कर अपने स्वयं के नाम स्थान को नियंत्रित करता है का उपयोग करें।

बेशक, आप हमेशा अपने नामस्थान को प्रदूषित करने से अपूर्ण मॉड्यूल रखने के लिए use Whatever(); कह सकते हैं, लेकिन यह बदसूरत है और आपको अपने पूरे नामस्थान को लिखने के लिए कठोर कोड के आसपास घूमना नहीं चाहिए।

+0

तो 'अपने मॉड्यूल qw (ab) का उपयोग करें;' और '@EXPORT qw (ab); 'अर्थहीन है? यदि नहीं, तो मुझे अभी भी नहीं पता कि हमें क्यों @ @ EXPORT_OK' – Jim

+3

@Jim 'हमारे @ निर्यात 'की आवश्यकता है जो आप डिफ़ॉल्ट रूप से निर्यात करते हैं (यानी,' आपका मॉड्यूल का उपयोग करें; ')। ऐसा करने पर * बुरा अभ्यास * माना जाता है। '@ 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 में कुछ डालने का कहना है, "यह केवल मेरे उपयोगकर्ताओं को दें यदि वे इसके लिए पूछें"। चूंकि हमने यहां आयात किए जाने के लिए do_awesome_thing स्पष्ट रूप से पूछे बिना use MyOtherPackage कहा है, यह आयात नहीं किया जाता है, और केवल पैकेज नाम निर्दिष्ट करके ही पहुंच योग्य है।

आयात करने के लिए do_awesome_thing के लिए जिस तरह से आप use MyOtherPackage qw(do_awesome_thing)mynewscript.pl की दूसरी पंक्ति में कहें। यह कहता है कि मॉड्यूल आयात करें और 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_OK' अधिकतर काम करते हैं: किसी भी मामले में उपयोगकर्ता उन नामों की सूची निर्दिष्ट कर सकता है, जिन्हें वे आयात करना चाहते हैं। वे * केवल * भिन्न होते हैं जब उपयोगकर्ता * आयात करने के लिए नामों की कोई सूची प्रदान नहीं करता है * - उस स्थिति में, '@ निर्यात 'पर चीजें निर्यात की जाती हैं, और' EXPORT_OK' पर चीजें नहीं हैं। – tobyink

+1

@tobyink धन्यवाद, निर्यात के साथ बहुत काम नहीं किया है, इसलिए यह नहीं पता था कि मैंने अब उस हिस्से को बदल दिया है। इस बात की पुष्टि करने के लिए गुगलिंग करते समय मैं इस O'Reilly पुस्तक (http://docstore.mik.ua/orelly/perl/advprog/ch06_05.htm) में आया था, जो एक ही गलती करने के लिए प्रतीत होता है: "यदि मॉड्यूल निर्यात का उपयोग करता है EXPORT_OK की बजाय, उपयोगकर्ता को सभी निर्यात किए गए प्रतीकों को प्राप्त किया जाता है, भले ही उनका आयात सूची में उल्लेख किया गया हो या नहीं। " लेकिन मैंने व्यवहार का परीक्षण किया है और पुष्टि की है कि आप सही थे और पुस्तक (स्पष्ट रूप से) गलत थी। – sundar