$ LOAD_PATH (रूबी) के लिए एक निर्देशिका जोड़ना


96

मैंने फ़ाइल की निर्देशिका को वर्तमान में $ LOAD_PATH (या $ :) में निष्पादित करने के लिए आमतौर पर इस्तेमाल की जाने वाली दो तकनीकों को देखा है। मैं ऐसा करने के फायदे देखता हूं कि आप एक मणि के साथ काम नहीं कर रहे हैं। एक स्पष्ट रूप से दूसरे की तुलना में अधिक क्रियात्मक लगता है, लेकिन क्या एक दूसरे के साथ जाने का कारण है?

पहली, क्रिया विधि (ओवरकिल हो सकती है):

$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))

और अधिक सीधा, त्वरित और गंदा:

$:.unshift File.dirname(__FILE__)

किसी एक के साथ जाने का कोई कारण?


2
एक क्रिया का थोड़ा कम वर्बोज़ संस्करण है:File.expand_path(File.dirname(__FILE__)).tap {|pwd| $LOAD_PATH.unshift(pwd) unless $LOAD_PATH.include?(pwd)}
नाथन लॉन्ग

"जब तक" खंड के बारे में कैसे? ऊपर के दोनों कैसे बराबर हो सकते हैं?
जूल

किसी व्यक्ति के रूप में जो यह समझने की कोशिश करने के लिए यहां आया था कि यह सुपर क्रिप्टिक है। मैं यह नहीं देखता कि उदाहरणों में निर्देशिका नाम कहाँ से आ रहा है। अगर कोई इसे स्पष्ट कर सकता है तो मैं सराहना करूंगा।
SlySherZ

1
__dir__(रूबी 2.0 के रूप में) का उपयोग करके इनमें से किसी को भी संक्षिप्त बना सकते हैं।
नाथन लॉन्ग

जवाबों:


51

मैं कहूंगा कि $:.unshift File.dirname(__FILE__)दूसरे के साथ जाना होगा , बस इसलिए कि मैंने $LOAD_PATHएक की तुलना में कोड में इसका अधिक उपयोग देखा है , और यह बहुत छोटा है!


जब मैंने पहली बार रूबी के साथ शुरुआत की, तो मैंने स्पष्ट रूप से सोचा कि $ LOAD_PATH बेहतर था। लेकिन एक बार जब आप शुरुआती स्थिति से स्नातक हो जाते हैं, तो मैं केवल $ LOAD_PATH का उपयोग करूंगा यदि मैं अपने कोड को शुरुआती के लिए अधिक पठनीय बनाने की कोशिश कर रहा था। मेह ने इसका व्यापार बंद कर दिया। यह इस बात पर निर्भर करता है कि कोड "सार्वजनिक" कैसे है, इसलिए जब तक मेमोरी का उपयोग प्रत्येक के लिए समान है, जो मुझे लगता है कि यह अनिवार्य रूप से है।
बोल्डर_ब्रुबी

9
शैली गाइड पर निर्भर करता है जिसे आप अपने प्रोजेक्ट के लिए अनुसरण करते हैं। लोकप्रिय रूबी स्टाइल गाइड कहती है, "पर्ल-स्टाइल विशेष चर (जैसे $ :, $ ;, आदि) के उपयोग से बचें। वे काफी गूढ़ हैं और किसी भी चीज़ में उनका उपयोग होता है लेकिन एक-लाइनर स्क्रिप्ट को हतोत्साहित किया जाता है।"
बोबामागू

152

रूबी लोड पथ को आमतौर पर $ के रूप में लिखा गया देखा जाता है: लेकिन सिर्फ इसलिए कि यह छोटा है, इसे बेहतर नहीं बनाता है। यदि आप स्पष्टता को चतुरता पसंद करते हैं, या यदि स्वयं की खातिर संक्षिप्तता आपको खुजली करती है, तो आपको इसे सिर्फ इसलिए नहीं करना चाहिए क्योंकि बाकी सभी हैं। हैलो बोलो ...

$LOAD_PATH

... और अलविदा कहें ...

# I don't quite understand what this is doing...
$:

29
इसके अलावा, "$:" जैसे स्ट्रिंग के लिए Google के लिए बहुत कठिन है जिसमें केवल प्रतीक हैं।
DSimon

23

मैं 'जल्दी-और-गंदे' तरीके से बहुत शौकीन नहीं हूं। रूबी के लिए कोई भी नया विचार होगा $:.

मुझे यह अधिक स्पष्ट लगता है।

libdir = File.dirname(__FILE__)
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)

या अगर मुझे पूरा रास्ता होने की परवाह है ...

libdir = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)

अद्यतन 2009/09/10

देर से मैं निम्नलिखित कर रहा हूँ:

$:.unshift(File.expand_path(File.dirname(__FILE__))) unless
    $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))

मैंने इसे GitHub ब्राउज़ करते समय विभिन्न रूबी परियोजनाओं के एक पूरे समूह में देखा है।

अधिवेशन होने लगता है?


@ ल्यूकंटिन्स, यह वास्तव में बहुत अच्छा है लेकिन मुझे आवेदन में कहां से "बूटस्ट्रैप" load_path करना चाहिए?
गॉसब्लाउर्स्की

@gaussblurinc कहीं न कहीं 'लिब / एप्लीकेशन' के शीर्ष पर है, लेकिन यह वास्तव में निर्भर करता है। यदि आपके पास एक binफ़ाइल थी जो हमेशा आपके सापेक्ष थी codeऔर यह केवल binफ़ाइल द्वारा चलाया गया था ... बिन में बूटस्ट्रैप। यदि आपके पास एक पुस्तकालय है, तो आप लाइब्रेरी कोड के शीर्ष पर बूटस्ट्रैप कर सकते हैं जैसे lib/code.rbकि सब कुछ के तहत एक्सेस प्राप्त करना lib/code/। आशा है कि यह रामबाण मदद करेगा!
ल्यूक एंटीन्स

1
RuboCop मुझे सूचित करता है कि __dir__वर्तमान फ़ाइल की निर्देशिका के लिए एक रास्ता पाने के लिए इस्तेमाल किया जा सकता है।
राफेल

8

यदि आप script/consoleअपनी रेल परियोजना में टाइप करते हैं और प्रवेश करते हैं $:, तो आपको एक सारणी मिलेगी जिसमें रूबी को लोड करने के लिए आवश्यक सभी निर्देशिकाएं शामिल हैं। इस छोटी सी एक्सरसाइज से टेक-ऑफ एक ऐसी बात $:है। ऐसा होने के कारण, आप इस पर कार्य कर सकते हैं जैसे unshiftविधि या <<ऑपरेटर के साथ अन्य निर्देशिकाओं को तैयार करना । अगर आप अपने विवरण में निहित के रूप में $:और $LOAD_PATHएक ही हैं।

आपके द्वारा बताए गए त्वरित और गंदे तरीके से इसे करने का नुकसान यह है: यदि आपके पास पहले से ही अपने बूट पथ में निर्देशिका है, तो यह खुद को दोहराएगा।

उदाहरण:

मेरे पास एक प्लगइन है जिसे मैंने टूडू कहा है। मेरी निर्देशिका इस तरह संरचित है:

/ --- विक्रेता
  |
  | --- / plugins
        |
        | --- / कार्यसूची
              |
              | --- / lib
                    |
                    | --- / ऐप्स
                          |
                          | --- / मॉडल
                          | --- / नियंत्रकों
              |
              | --- / रेल
                    |
                    | --- init.rb

Init.rb फ़ाइल में मैंने निम्नलिखित कोड दर्ज किया है:

## In vendor/plugins/todo/rails/init.rb
    %w{ models controllers models }.each do |dir|
      path = File.expand_path(File.join(File.dirname(__FILE__), '../lib', 'app', dir))
      $LOAD_PATH << path
      ActiveSupport::Dependencies.load_paths << path
      ActiveSupport::Dependencies.load_once_paths.delete(path)
    end 

ध्यान दें कि मैं ब्लॉक के अंदर की क्रियाओं को 'मॉडल', 'कंट्रोलर' और 'मॉडल' के लिए कोड ब्लॉक को कैसे बताऊं, जहां मैं 'मॉडल' दोहराता हूं। (FYI करें, %w{ ... }रूबी को यह बताने के लिए कि स्ट्रिंग्स की एक सरणी रखने का एक और तरीका है)। जब मैं दौड़ता हूं script/console, तो मैं निम्नलिखित टाइप करता हूं:

>> puts $:

और मैं इसे टाइप करता हूं ताकि सामग्री को स्ट्रिंग में पढ़ना आसान हो। मुझे जो आउटपुट मिलता है वह है:

...
...
./Users/Me/mySites/myRailsApp/vendor/plugins/todo/lib/app/models
./Users/Me/mySites/myRailsApp/vendor/plugins/todo/lib/app/controllers
./Users/Me/mySites/myRailsApp/vendor/plugins/todo/lib/app/models

जैसा कि आप देख सकते हैं, हालांकि यह एक उदाहरण के रूप में एक उदाहरण है जिसे मैं एक परियोजना का उपयोग करते समय बना सकता हूं, जिस पर मैं वर्तमान में काम कर रहा हूं, यदि आप जल्दी और गंदे तरीके से सावधान नहीं हैं, तो दोहराया मार्ग को बढ़ावा मिलेगा। लंबा रास्ता दोहराया रास्तों के लिए जाँच करेगा और सुनिश्चित करेगा कि वे घटित न हों।

यदि आप एक अनुभवी रेल प्रोग्रामर हैं, तो आपको शायद इस बात का बहुत अच्छा अंदाजा है कि आप क्या कर रहे हैं और संभवत: दोहराए जाने वाले रास्तों की गलती न करें। यदि आप एक नौसिखिया हैं, तो जब तक आप वास्तव में समझ नहीं लेते कि आप क्या कर रहे हैं, तब तक मैं साथ रहूँगा।


आपकी प्रतिक्रिया बहुत उपयोगी है और अच्छी तरह से समझाया गया है। सुझाया गया संपादन: विधि load_pathsऔर load_once_paths.deleteपदावनत किया गया है। उन रेखाओं को अद्यतन करने में मदद की जाएगी जो उन्हें संदर्भित करती हैं: ActiveSupport::Dependencies.autoload_paths << path ActiveSupport::Dependencies.autoload_once_paths.delete(path)
उलजार

8

बेस्ट मैं Rspec का उपयोग करते समय रिश्तेदार पथ के माध्यम से एक dir जोड़ने के लिए भर में आए हैं। मुझे लगता है कि यह पर्याप्त है लेकिन अभी भी एक अच्छा एक लाइनर है।

$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))

1

एक रत्न है जो आपको अपने लोड पथ को अच्छे और क्लीनर कोड के साथ सेटअप करने देगा। : इस की जाँच करें https://github.com/nayyara-samuel/load-path

इसके अच्छे दस्तावेज भी हैं


-2

मुझे पता है कि यह प्रश्न पूछे जाने के बाद एक लंबा समय हो गया है, लेकिन मेरे पास एक अतिरिक्त उत्तर है जिसे मैं साझा करना चाहता हूं।

मेरे पास कई रूबी अनुप्रयोग हैं जो किसी अन्य प्रोग्रामर द्वारा कई वर्षों में विकसित किए गए थे, और वे विभिन्न अनुप्रयोगों में समान कक्षाओं का फिर से उपयोग करते हैं, हालांकि वे एक ही डेटाबेस तक पहुंच सकते हैं। चूंकि यह DRY नियम का उल्लंघन करता है, इसलिए मैंने रूबी के सभी अनुप्रयोगों द्वारा साझा की जाने वाली एक क्लास लाइब्रेरी बनाने का फैसला किया। मैं इसे मुख्य रूबी पुस्तकालय में रख सकता था, लेकिन यह सामान्य कोडबेस में कस्टम कोड छिपाएगा जो मैं नहीं करना चाहता था।

मुझे एक समस्या थी जहां मेरे पास पहले से परिभाषित नाम "profile.rb" के बीच एक नाम संघर्ष था, और एक वर्ग जो मैं उपयोग कर रहा था। जब तक मैंने कॉमन कोड लाइब्रेरी बनाने की कोशिश नहीं की, यह संघर्ष एक समस्या नहीं थी। आम तौर पर, रूबी पहले आवेदन स्थानों को खोजती है, फिर $ LOAD_PATH स्थानों पर जाती है।

Application_controller.rb मेरे द्वारा बनाई गई कक्षा को नहीं ढूंढ सका, और मूल परिभाषा पर एक त्रुटि फेंक दी क्योंकि यह एक वर्ग नहीं है। चूंकि मैंने एप्लिकेशन की एप्लिकेशन / मॉडल अनुभाग से वर्ग परिभाषा को हटा दिया था, रूबी वहां नहीं मिली और रूबी पथों में इसे ढूंढती रही।

इसलिए, मैंने लाइब्रेरी डायरेक्टरी का एक पथ शामिल करने के लिए $ LOAD_PATH चर को संशोधित किया। यह आरंभीकरण समय में environment.rb फ़ाइल में किया जा सकता है।

यहां तक ​​कि नई निर्देशिका के साथ खोज पथ में जोड़ा गया, रूबी एक त्रुटि फेंक रही थी क्योंकि यह पहले से सिस्टम-परिभाषित फ़ाइल को प्राथमिकता से ले रहा था। $ LOAD_PATH चर में खोज पथ अधिमानतः रूबी पथों को पहले खोजता है।

इसलिए, मुझे खोज क्रम में बदलाव करने की आवश्यकता थी ताकि रूबी को मेरे सामान्य पुस्तकालय में कक्षा मिल जाए, इससे पहले कि यह अंतर्निहित पुस्तकालयों की खोज की जाए।

इस कोड ने इसे environment.rb फ़ाइल में किया:

Rails::Initializer.run do |config|

* * * * *

path = []
path.concat($LOAD_PATH)
$LOAD_PATH.clear
$LOAD_PATH << 'C:\web\common\lib'
$LOAD_PATH << 'C:\web\common'
$LOAD_PATH.concat(path)

* * * * *

end

मुझे नहीं लगता कि आप इस स्तर पर पहले दिए गए किसी भी उन्नत कोडिंग निर्माण का उपयोग कर सकते हैं, लेकिन यह ठीक काम करता है यदि आप अपने ऐप में शुरुआती समय में कुछ सेटअप करना चाहते हैं। आपको मूल $ LOAD_PATH चर के मूल क्रम को बनाए रखना चाहिए जब इसे नए चर में वापस जोड़ा जाए अन्यथा कुछ मुख्य रूबी वर्ग खो जाते हैं।

Application_controller.rb फ़ाइल में, मैं बस एक का उपयोग करता हूं

require 'profile'
require 'etc' #etc

और यह पूरे आवेदन के लिए कस्टम लाइब्रेरी फ़ाइलों को लोड करता है, अर्थात, मुझे प्रत्येक नियंत्रक में कमांड की आवश्यकता का उपयोग करने की आवश्यकता नहीं है।

मेरे लिए, यह वह समाधान था जिसकी मैं तलाश कर रहा था, और मुझे लगा कि मैं इस उत्तर को इस जानकारी के साथ जोड़ने के लिए जोड़ दूंगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.