2009-05-26 8 views
27

रूबी कार्यक्रम में आवश्यक पथों का प्रबंधन करने का सबसे अच्छा तरीका क्या है?रूबी पथ प्रबंधन

मुझे एक बुनियादी उदाहरण दे की तरह एक संरचना पर विचार करें,:

\MyProgram 

\MyProgram\src\myclass.rb 

\MyProgram\test\mytest.rb 

अपने परीक्षण में मैं require '../src/myclass' का उपयोग तो मैं केवल \MyProgram\test फ़ोल्डर से परीक्षण कॉल कर सकते हैं, लेकिन मैं इसे कॉल करने के लिए सक्षम होने के लिए चाहते हैं किसी भी रास्ते से!

ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(ROOT) और फिर हमेशा require "#{ROOT}/src/myclass"

वहाँ यह करने के लिए एक बेहतर तरीका है का उपयोग करें:

समाधान मैं के साथ आया था सभी स्रोत में परिभाषित करने के लिए है निम्न पंक्ति फ़ाइलें? आदि स्पष्ट रूप से जब आप आप रूट की आपूर्ति करने की जरूरत नहीं है

$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "src")) 

$ LOAD_PATH (उर्फ $ :) करने के लिए अपने स्रोत के लिए पथ prepending द्वारा:

उत्तर

12

यहाँ एक थोड़ा संशोधित यह करने के लिए रास्ता है आपके कोड की आवश्यकता है यानी require 'myclass'

1

श्रीस का जवाब मानक दृष्टिकोण है।

एक और तरीका आपके कोड को मणि के रूप में पैकेज करना होगा। फिर rubygems यह सुनिश्चित करने का ख्याल रखेगा कि आपकी लाइब्रेरी फाइलें आपके रास्ते में हैं।

9

एक ही है, कम शोर IMHO:

$:.unshift File.expand_path("../../src", __FILE__) 
require 'myclass' 

या सिर्फ

require File.expand_path "../../src/myclass", __FILE__ 

रूबी 1.8.7 और 1.9.0 पर (डेबियन) लिनक्स के साथ परीक्षण किया गया - कृपया मुझे बताओ अगर यह पर काम करता है विंडोज़ भी।

क्यों एक आसान विधि (उदाहरण के लिए 'उपयोग', 'requ_relative', या इस तरह एसजी) मानक lib में नहीं बनाया गया है?

# Read application config              
$hConf, $fConf = {}, File.expand_path("../config.rb", __FILE__) 
$hConf = File.open($fConf) {|f| eval(f.read)} if File.exist? $fConf 

    # Application classpath               
$: << ($hConf[:appRoot] || File.expand_path("../bin/app", __FILE__)) 

    # Ruby libs                  
$lib = ($hConf[:rubyLib] || File.expand_path("../bin/lib", __FILE__)) 
($: << [$lib]).flatten! # lib is string or array, standardize      

तो मैं सिर्फ इतना है कि इस स्क्रिप्ट एक बार कहा जाता है सुनिश्चित करने की आवश्यकता: -: अद्यतन एक setenv खोल स्क्रिप्ट की एक रूबी संस्करण require_relative 1.9.x के बाद से वहाँ है

+0

, इस सबसे अच्छा विकल्प मैं इस _inside_ करने के लिए देखा है है अब तक रूबी का। – Matt

+0

यह कहना है कि, मैं रूबी पथ के पथ को जोड़ना (पूर्ववत नहीं करना) पसंद करता हूं, क्योंकि आप मानक रूबी पुस्तकालयों में मौजूद किसी चीज़ पर अनजाने में चिपकते नहीं हैं। – Matt

+0

क्या आपका मतलब यह नहीं था कि 'मैं इसके बजाय प्रीपेडिंग (संलग्न नहीं) पसंद करता हूं? (दूसरे शब्दों में: क्या आप वास्तव में यह सुनिश्चित करना नहीं चाहते हैं कि आपकी सामग्री को प्राथमिकता दी जाए?) मेरा मूल उदाहरण '$: << newpath' था जो जोड़ रहा था, अब इसे 'unshift' द्वारा तय किया गया था, जैसा कि पिछले उत्तर में किया गया था। धन्यवाद – inger

0

यह है कि मैं क्या साथ समाप्त हो गया है किसी और चीज से पहले, और व्यक्तिगत स्रोत फ़ाइलों को छूने की आवश्यकता नहीं है।

मैं बाहरी (गैर- मणि) पुस्तकालयों के स्थान की तरह एक कॉन्फ़िग फ़ाइल के अंदर कुछ विकल्प रखा,:

# Site- and server specific config - location of DB, tmp files etc. 
{ 
    :webRoot => "/srv/www/myapp/data", 
    :rubyLib => "/somewhere/lib", 
    :tmpDir => "/tmp/myapp" 
} 

यह अच्छी तरह से मेरे लिए काम कर रहा है, और मैं कई परियोजनाओं में setenv स्क्रिप्ट का पुन: उपयोग कर सकते हैं बस कॉन्फ़िगरेशन फ़ाइल में पैरामीटर बदलकर। शैल स्क्रिप्ट्स, आईएमओ से बेहतर विकल्प।

+0

@ जे-जी-फस्टस: "काम करने वाली निर्देशिका के साथ __ फ़ाइल __ विलय करना सुनिश्चित करता है कि मैं इसे कहीं से भी कॉल कर सकता हूं": File.expand_path (पथ, आधार) का एक ही प्रभाव होना चाहिए। क्या आप वाकई अदरक के उत्तर से नौकरी नहीं करते हैं? यह आपको क्या देता है? (इसे test.rb में डालें, उदाहरण के लिए): "फाइल.एक्सपैंड_पैथ" ../../src/myclass ", __ फ़ाइल __" – inger

+0

आप सही हैं, File.expand_path वही करता है। मैंने पोस्ट अपडेट किया है। यह थोड़ा क्लीनर बन गया है, धन्यवाद :) इसके अलावा, प्राथमिक अंतर यह है कि यह एप्लिकेशन स्टार्टअप पर एक बार एक अलग स्क्रिप्ट चलाया जाता है, और मुझे व्यक्तिगत स्रोत फ़ाइलों को स्पर्श करने की आवश्यकता नहीं होती है। –

30

रूबी 1.9 के रूप में आप यह करने के लिए require_relative उपयोग कर सकते हैं:

require_relative '../src/myclass' 

आप आप प्रति this SO comment के रूप में एक्सटेंशन मणि से प्राप्त कर सकते हैं पुराने संस्करणों के लिए इस की जरूरत है।

2
Pathname(__FILE__).dirname.realpath 

एक गतिशील तरीके से एक पूर्ण पथ प्रदान करता है। विशिष्ट फ़ोल्डर में सभी "rb" फ़ाइलें (=> रूबी 1.9) की आवश्यकता के लिए कोड निम्नलिखित

2

उपयोग: हालांकि यह मेरी रीढ़ की हड्डी झुनझुनी बनाता

path='../specific_folder/' # relative path from current file to required folder 

Dir[File.dirname(__FILE__) + '/'+path+'*.rb'].each do |file| 
    require_relative path+File.basename(file) # require all files with .rb extension in this folder 
end 
संबंधित मुद्दे