2009-04-25 7 views
35

मेरे पास foo नामक एक डीआईआर है, और इसमें मेरे पास lib और bin है। bin में लिपियों को lib में सामान की आवश्यकता है। मैं कुछ इस तरह करते हैं:मैं एक संबंधित स्थान से पर्ल मॉड्यूल का उपयोग कैसे करूं?

#!perl 
use strict; 
use warnings; 
use lib '../lib'; 
use Foo; # <-- comes from lib 

लेकिन इसका मतलब है कि मैं bin निर्देशिका स्क्रिप्ट चलाने के लिए में रहना होगा। निश्चित रूप से एक बेहतर तरीका है। ऐसा करने का सही तरीका क्या है?

+1

अपने जवाब मुझे नहीं कैसे एक रिश्तेदार स्थान से एक मॉड्यूल का उपयोग करने की थी –

उत्तर

47

मानक FindBin मॉड्यूल जो आप चाहते हैं वह करता है।

use FindBin; 
use lib "$FindBin::Bin/../lib"; 

perldoc FindBin और अधिक के लिए।

+0

[PerlMonks] के अनुसार (http://www.perlmonks.org/) एक FindBin से बचना चाहिए: "[FindBin टूटी हुई है (उत्तर: कैसे मैं स्क्रिप्ट पर कार्य करने के लिए पूरा पथ मिलता है)] (http: // www.perlmonks.org/?node_id=41213) "। - हालांकि, स्वीकार्य रूप से, यह पोस्टिंग 10 साल से अधिक (वर्ष 2000 से) है और मुझे पूरी तरह से यकीन नहीं है कि यह अभी भी सटीक है। – zrajm

+0

बहुत बढ़िया! यह एकमात्र समाधान है जो बॉक्स से बाहर काम करता है। मैंने शुरुआती {पुश @INC, "$ mypath"} जैसी बड़ी बंदूकें की कोशिश की, और उन्होंने आसानी से काम नहीं किया। धन्यवाद! – kakyo

5

__FILE__ के माध्यम से अपने .pl पूर्ण पथ बाहर पार्स और और अंत पर ../lib कील या split(/\//,__FILE__) के अंतिम तत्व बंद पॉप और उस के लिए /lib जोड़ें।

+0

यह क्यों मतदान किया गया? यह सबसे अच्छा जवाब जैसा लगता है क्योंकि यह हमेशा काम करेगा ... –

+0

इसके लिए सभी perl फ़ाइलों को संशोधित करने की आवश्यकता है। – ojblass

-3

के बारे में कैसे:

BEGIN: { 
    push @INC, '/full/path/to/lib'; 
} 

एक रिश्तेदार संदर्भ मान लें कि आप बिन निर्देशिका में रखने के लिए जा रहे हैं, इसलिए बजाय वहाँ सापेक्ष संदर्भ सम्मिलित करने के लिए।

+0

प्रश्न पर ध्यान दें: यह वास्तव में मुझे नहीं बताता है कि रिश्तेदार उपयोग कैसे करें। –

+0

शायद आप अंत में बजाय @INC के सामने विशेष पथ रखना चाहते हैं। –

+0

टाइपिंग बहुत जल्दी: -) ... @frew - स्रोत कोड पूरी तरह से योग्य पथ के लिए है - मेरी टिप्पणी में मैं समझाने एक रिश्तेदार पथ डालने के लिए। @bdf - हाँ आप prb हैं। ठीक है, ऐसा करने के लिए एक पुश के बजाय 'unshift' होगा। –

3

"FindBin" मॉड्यूल केवल तभी काम करेगा यदि पर्ल स्क्रिप्ट में स्थित निर्देशिका आपके सिस्टम पाथ में है, अन्यथा यह असफल हो जाएगी। पर काबू पाने के लिए आप $0 मान को अपने पथ-से-perl-module जानकारी प्राप्त करने के लिए उपयोग कर सकते हैं और मान को use lib पर पास कर सकते हैं।

कुछ इस तरह -

BEGIN { 
    use File::Spec::Functions qw(rel2abs); 
    use File::Basename qw(dirname); 

    #Covert the script path to absolute and get its directory name 
    our $path = dirname(rel2abs($0)); 

    #Replace the bin tag with lib to get module directory 
    $path =~ s{bin/?$}{lib}; 
} 

use lib $path; 

संपादित करें: FindBin मॉड्यूल बस पूरी तरह से काम करता है और Michael's answer में वर्णित के रूप में इस्तेमाल किया जा सकता है। इसकी कार्यप्रणाली की मेरी समझ अपूर्ण थी और इसलिए मुझे पहली टिप्पणी करने के लिए प्रेरित किया जो अब मैं वापस लेता हूं। वैसे भी, मुझे कोई कारण नहीं दिख रहा है कि इस विधि को FindBin (TMTOWTDI) का उपयोग करके हासिल की जा सकने वाली कुछ और लाइनों के बावजूद क्यों काम नहीं करना चाहिए।

+0

यह हाल ही में मुझे थोड़ा सा है क्योंकि rel2abs गलत विंडोज पथ वापस दे सकता है। फ़ाइल :: Spec :: Win32 :: rel2abs Cwd :: getdcwd को कॉल करने और गलत चीज़ को वापस करने का अंत हो सकता है। मुझे इस बारे में जानने के लिए आर्काइव :: निकालने के लिए एक पैच जमा करना पड़ा: http://rt.cpan.org/Public/Bug/Display.html?id=43278 –

+0

FindBin उन स्थानों के लिए ठीक काम करता है जो आपके नहीं हैं पथ। आईआईआरसी यह विफल रहता है अगर आपके पथ में आपकी स्क्रिप्ट के समान नाम वाली एक (अलग) फ़ाइल है। –

+0

आपकी विधि वास्तव में FindBin पहले से ही समान है, लेकिन क्रॉस-प्लेटफ़ॉर्म प्यार के बिना। वास्तव में। FindBin जाने का रास्ता है। –

3

मैं आमतौर पर इस तकनीक का उपयोग करता हूं। इसके उदासी मेरी पीएचपी दिनों से प्रेरित:

स्थितियों में इसका काम जहाँ आप जानते हैं, जहां किसी दिए गए फ़ाइल वर्तमान एक के सापेक्ष जाएगा, और प्रवेश की यकीन है कि यह में कहा जा सकता है बिंदुओं नहीं हैं या आसपास के कॉलटाइम पर पर्यावरण।

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

use File::Basename(); 
use Cwd   (); 
my $base_dir; 
my $relative_path; 
BEGIN { 
    $realitive_path = '../../' # Path to base of project relative to the current file 
    $base_dir = Cwd::realpath(File::Basename::dirname(__FILE__) .'/' . $relative_path); 
} 


use lib "${base_dir}/lib"; 
use Foo; 

आदर्श रूप में वहाँ कुछ मॉड्यूल कहीं कि यह करता है होना चाहिए, अगर नहीं, मैं आधे से एक लिखने के लिए परीक्षा रहा हूँ:

use Some::Module(); 
use lib Some::Module::relative_self('../../lib', __FILE__); 
+0

कॉलर() से __FILE__ प्राप्त करने के लिए यह संभवतः संभवतः संभव है।/मुझे लगता है कि –

+0

नहीं, FindBin – singingfish

+0

पर जाएं मुझे खोजन पर एक नज़र डालें, और यह औसत उपयोग के मामले को कवर करता है, लेकिन जिस तरह से यह कुछ अन्य मामलों के लिए काम करता है और यह कोड में यह कैसे करता है वह भयानक है। उपयोग() समय पर एक चर बनाने के लिए बस मेरे लिए वास्तव में अजीब है। –

0

मेरे समाधान:

use lib substr(__FILE__, 0, rindex (__FILE__, "/")); 
+1

रेगेक्स का उपयोग करने की तुलना में थोड़ा सा झुका हुआ लगता है? यह भी ध्यान रखें कि '__FILE__' में कभी-कभी * रिश्तेदार * फ़ाइल नाम हो सकता है (उदा। '।/ myscript') जो आपको काट सकता है (या शायद नहीं)। – zrajm

0

बस जोड़ने के लिए मेरे अपने दो सेंट जवाब के इस संग्रह के लिए, मैं आमतौर पर इन पंक्तियों के साथ कुछ का उपयोग कर इस समस्या का समाधान:

use lib do { 
    use Cwd 'realpath'; 
    my ($dir) = __FILE__ =~ m{^(.*)/}; # $dir = path of current file 
    realpath("$dir/../lib");   # path of '../lib' relative to $dir 
}; 

मैं एक do ब्लॉक का उपयोग क्योंकि सब कुछ की जरूरत है तो बड़े करीने से उसमें निहित है पसंद है। यदि आपको कभी भी कॉपी/पेस्ट करने की आवश्यकता है, या बाद में अपने कोड को समझने का प्रयास करें तो आपको अलग BEGIN ब्लॉक या उसके जैसा कुछ भी देखने की आवश्यकता नहीं है।

उपरोक्त कोड naEvely मानता है कि / एक डीआईआर/फ़ाइल नाम विभाजक के रूप में उपयोग किया जाता है।

0
use lib './'; 

मेरे लिपि के समान निर्देशिका में फ़ाइलों को शामिल करने के लिए लिनक्स बॉक्स पर पर्ल v5.14.2 के साथ मेरे लिए काम कर रहा है।

शायद आप अपनी स्क्रिप्ट का कार्यशील निर्देशिका के तहत अपने lib और बिन निर्देशिका ले जाएँ और का उपयोग कर उन्हें संदर्भित करने के लिए प्रयास करने के लिए के लिए यह काम करेगा

use lib './bin/'; 
+1

मुझे यकीन नहीं है कि क्या फ्यू इस समाधान की तलाश में था। अगर मैं गलत हूं तो मुझे सही करें लेकिन वह वास्तव में कामकाजी निर्देशिका के बाहर पुस्तकालयों को शामिल करने का एक बेहतर तरीका चाहता था। आप जो रिपोर्ट कर रहे हैं वह सभी परियोजनाओं के लिए संभव नहीं हो सकता है – comiventor

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

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