2010-03-26 15 views
13

यदि मेरा पर्ल प्रोग्राम पर्ल मॉड्यूल का उपयोग करता है, तो यह कैसे निर्धारित करेगा कि मॉड्यूल कोड वाली फ़ाइल को कहां ढूंढना है?पर्ल प्रोग्राम कैसे पता चलता है कि फ़ाइल को पर्ल मॉड्यूल युक्त फ़ाइल कहां मिलती है?

उदाहरण के लिए, इस कार्यक्रम में शामिल है, तो:

use MyModule1;    # Example 1 
use This::Here::MyModule2; # Example 2 

जहां यह कैसे दिखेंगे?

+0

मुझे इस प्रश्न का व्यापक उत्तर नहीं मिला कि मैं लिंक कर सकता हूं, इसलिए मैंने एक बनाने का फैसला किया। यदि नीचे दिए गए उत्तर को जोड़ों/सुधारों की आवश्यकता है, तो कृपया इसे प्राप्त करें :) – DVK

उत्तर

13

पर्ल दुभाषिया (जो आपके पर्ल प्रोग्राम चलाता है) मॉड्यूल युक्त फ़ाइल की खोज के लिए @INC नामक एक विशेष सरणी का उपयोग करेगा।

@INC सरणी में प्रत्येक मान एक निर्देशिका नाम है (लेकिन से नीचे नोट देखें); पर्ल नीचे निर्दिष्ट नियमों का उपयोग करके लूप में उन निर्देशिकाओं के भीतर खोज करेगा। (कृपया this SO post for details of how the contents of @INC are determined देखें)।

यदि मॉड्यूल की फ़ाइल @INC को समाप्त करने के बाद नहीं मिली है, तो प्रोग्राम का संकलन एक त्रुटि के साथ निरस्त कर दिया जाएगा। यदि मॉड्यूल की फ़ाइल @INC में निर्दिष्ट निर्देशिकाओं में से एक में पाई जाती है, तो खोज शेष @INC को देखे बिना समाप्त हो जाती है।

रास्ता पर्ल @INC में सूचीबद्ध निर्देशिका में से प्रत्येक के भीतर एक मॉड्यूल फ़ाइल के लिए खोज करता इस प्रकार है:

  • सबसे पहले, यह मॉड्यूल का नाम के श्रेणीबद्ध घटकों (:: द्वारा अलग शब्द), अलग में होगा अंतिम घटक - जिसका उपयोग फ़ाइल नाम बनाने के लिए किया जाएगा - और एक पदानुक्रम पथ (अंतिम :: से पहले के सभी घटक)।

    यदि मॉड्यूल नाम में केवल एक घटक है (::, उदाहरण के लिए MyModule1), पदानुक्रम पथ खाली है और फ़ाइल नाम मॉड्यूल का नाम है। इस प्रश्न में दूसरे उदाहरण में, अंतिम घटक MyModule2 है और पदानुक्रम पथ This::Here होगा।

  • अपेक्षित फ़ाइल नाम मॉड्यूल नाम के अंतिम घटक को .pm एक्सटेंशन के साथ जोड़कर निर्धारित किया जाएगा। जैसे हमारे उदाहरणों में MyModule1.pm और MyModule2.pm

    नोट: मॉड्यूल नाम स्पष्ट रूप से यूनिक्स और अन्य ऑपरेटिंग सिस्टम पर संवेदनशील हैं जहां फ़ाइल/निर्देशिका नामकरण केस संवेदनशील है।

  • मॉड्यूल की निर्देशिका द्वारा निर्धारित किया जाएगा:

    1. @INC से अगले निर्देशिका लेना - एक उदाहरण

    2. पदानुक्रम लेने के द्वारा उस निर्देशिका की एक उप-निर्देशिका बनाने के रूप में /usr/lib/perl मान लीजिए मॉड्यूल नाम का पथ (यदि कोई है) और "::" / के साथ बदल रहा है या ऑपरेटिंग सिस्टम जो भी चरित्र निर्देशिका विभाजक के रूप में उपयोग करता है। हमारे दो उदाहरणों में, पहले मॉड्यूल की खोज /usr/lib/perl (कोई उप-निर्देशिका नहीं) और दूसरी /usr/lib/perl/This/Here में की जाएगी।

    3. नोट: ऊपर एक मामूली सरलीकरण है - @INCmay also contain subroutine references and object references, के रूप में अपने कस्टम कोड के बजाय 2 तर्क ऊपर # में विनिर्दिष्ट निर्देशिका में देखने के प्रदर्शन के निर्दिष्ट करता है जो मॉड्यूल लोड। यह कार्यक्षमता बहुत ही कम प्रतीत होती है और यह आलेख मानता है कि संपूर्ण @INC में केवल निर्देशिकाएं हैं। ("/usr/lib/perl", "/opt/custom/lib"):

के एक विशिष्ट उदाहरण पर चलते हैं, यह सोचते हैं कि आपके @INC दो उप-निर्देशिका में शामिल करते हैं।

फिर पर्ल के रूप में इस खोज करेंगे:

 
========================================================================== 
| Module    | Try # | File to try    
========================================================================== 
| MyModule1    | Try 1 | /usr/lib/perl/MyModule1.pm 
| MyModule1    | Try 2 | /opt/custom/lib/MyModule1.pm 
========================================================================== 
| This::Here::MyModule2 | Try 1 | /usr/lib/perl/This/Here/MyModule2.pm 
| This::Here::MyModule2 | Try 2 | /opt/custom/lib/This/Here/MyModule2.pm 
========================================================================== 

कृपया याद करते हैं कि पर्ल दुभाषिया एक बार यह स्थानों में से एक में फ़ाइल पाता खोज करने के लिए कोशिश कर बंद हो जाएगा, अगर फाइल बाद में स्थानों में है देखने के लिए कोशिश कर के बिना भी। जैसे यदि /usr/lib/perl/This/Here/MyModule2.pm मौजूद है, तो पर्ल /opt/custom/lib/This/Here/MyModule2.pm के अस्तित्व के बारे में नहीं देखेगा, न ही देखभाल करेगा।

नोट: जब भी पर्ल दुभाषिया require का उपयोग कर रहा है-पर्ल मॉड्यूल आयात करने के लिए तंत्र की तरह @INC का उपयोग किया जाता है। इसमें शामिल हैं:

  • require निर्देश ही
  • use MyModule बयान (आवश्यकता के बराबर + आयात)
  • use base (बराबर की आवश्यकता के लिए + "@ISA धक्का")
+2

शायद यह ध्यान देने योग्य है कि @INC की सामग्री कहां से आती है। यह ओपी की तलाश में भी जवाब हो सकता है। संक्षेप सारांश: मुख्य डिफ़ॉल्ट सामग्री अंतर्निहित हैं (पथों का सटीक विवरण आपकी स्थापना पर निर्भर करता है, जाहिर है)। अपनी स्क्रिप्ट के बाहर इसे संशोधित करने के प्राथमिक तरीके हैं पर्यावरण परिवर्तनीय PERL5LIB (पथों की एक कॉलन-सीमित सूची) सेट करना या रनटाइम पर निष्पादन योग्य को '-I/path/to/dir' विकल्प प्रदान करना। (ये सरणी में प्रीपेड) – Cascabel

+0

किसी के पास ठीक से एक अच्छी आधिकारिक सूची है कि @INC का निर्माण कैसे किया जाता है? Perldoc perlvar में से एक को PERL5LIB का कोई उल्लेख नहीं है, साथ ही '$ Config {sitelib}/sitecustomize.pl' तंत्र (जिसे संकलन समय में बनाया जाना है) में कोई अनुपलब्ध प्रतीत होता है। – Cascabel

+0

@ डीवीके: बढ़िया! गलती से माना जाता है कि आप इस सवाल पर टिप्पणी के कारण किए गए थे और तथ्य यह है कि यह पहले से ही पूरी तरह से पूरी तरह से है। – Cascabel

2

perlfunc documentation on use के अनुसार:

मॉड्यूल LI का उपयोग करें एसटी

नामित मॉड्यूल से वर्तमान पैकेज में कुछ अर्थशास्त्र आयात करता है, आम तौर पर आपके पैकेज में कुछ सबराउटिन या परिवर्तनीय नामों को अलियासिंग करके। यह

BEGIN { require Module; Module->import(LIST); } 

के बराबर है, सिवाय इसके कि मॉड्यूल एक शब्दकोष होना चाहिए।

तो require बड़े कार्य करने करता है, और require documentation

प्रदान करता है EXPR एक bareword है, का की आवश्यकता होती है एक ".pm" विस्तार हो जाती है और आप के लिए फ़ाइल नाम में "/" साथ "::" बदल देता है, यह आसान बनाने के लिए मानक मॉड्यूल लोड करने के लिए। मॉड्यूल लोड करने का यह रूप आपके नेमस्पेस को बदलने का जोखिम नहीं उठाता है।

दूसरे शब्दों में, अगर आप इस प्रयास करें:

require Foo::Bar; # a splendid bareword 

आवश्यकता समारोह वास्तव में निर्देशिका @INC सरणी में निर्दिष्ट में "Foo/Bar.pm" फ़ाइल के लिए दिखेगा।

5

हालांकि यह सीधे सवाल का जवाब नहीं देता है, यहां मॉड्यूल फ़ाइल का पूरा पथ निर्धारित करने के लिए कुछ सरल तकनीकें हैं जिनका आप उपयोग करना चाहते हैं।

कमांड लाइन से अन्य जानकारी के बहुत सारे के साथ @INC सरणी के डिफ़ॉल्ट सामग्री देखने के लिए,:

perl -V  

आप Carp मॉड्यूल के स्थान जानना चाहते हैं:

perldoc -l Carp 

एक स्क्रिप्ट के अंदर, %INC हैश की सामग्री को मुद्रित करने के लिए उपयोगी मॉड्यूल निर्धारित करने के लिए उपयोगी है, खासकर यदि आपने @INC को इसके डिफ़ॉल्ट से संशोधित किया है:

use Carp; 
print $INC{'Carp.pm'}; 

यह सरल स्क्रिप्ट भी Find installed Perl modules matching a regular expression के लिए इस्तेमाल किया जा सकता है और अलग निर्देशिका में किसी भी डुप्लिकेट मॉड्यूल की पहचान।

+0

@toolic में subroutine संदर्भ और ऑब्जेक्ट्स रखने की क्षमता का संदर्भ भी जोड़ा - यह उत्तर निकटता से संबंधित है ओपी सवाल, लेकिन मुझे लगता है कि यह कुछ हद तक अलग है (उदाहरण के लिए "जहां से आयात किया गया मॉड्यूल आया था")। क्या आप इसे एसओ पर एक अलग क्यू + ए के रूप में पोस्ट करना चाहते हैं (मैं इसे लिंक करूंगा), या मुझे एक अलग क्यू के रूप में पूछने और अपना उत्तर पोस्ट करने के लिए आपकी सहमति दे रहा हूं (या मुझे अपना दोबारा पोस्ट करने दे रहा है)? – DVK

+0

किया गया! http://stackoverflow.com/questions/2527990/how-do-i-find-which-file-contains-perl-module-my-script-uses – DVK

+0

@ डीवीके - अगर मेरे विंडोज़ पथ में पर्ल के दो संस्करण हैं पर्यावरण चर, तो सिस्टम कैसे पता लगाता है कि कौन सी perl चुनने के लिए? क्या यह पहला है? मेरे मशीन पर स्थापित विभिन्न सॉफ़्टवेयर के लिए मेरे पास अलग-अलग perls हैं। वे सॉफ्टवेयर के साथ स्थापित किया गया था। – stack1

संबंधित मुद्दे