2010-05-24 22 views
154

रूबी 1.9.2 करने के लिए नवीनतम changesets अब आपके पास अपने LOAD_PATH की वर्तमान निर्देशिका . हिस्सा बनाते हैं। मैं Rakefiles की एक गैर तुच्छ संख्या कि मान लेते हैं कि .LOAD_PATH का हिस्सा है है, इसलिए यह उन्हें तोड़ दिया (वे सब बयान है कि बंद परियोजना पथ आधारित की आवश्यकता के लिए "लोड करने के लिए ऐसी कोई फाइल" सूचना)। क्या ऐसा करने के लिए कोई विशेष औचित्य था?रुबी 1.9.2 क्यों हटाता है "।" LOAD_PATH से, और विकल्प क्या है?

एक फिक्स का सवाल है, $: << "." जोड़ने हर जगह काम करता है, लेकिन अविश्वसनीय रूप से hacky लगता है और मुझे लगता है कि ऐसा करने के लिए नहीं करना चाहती। मेरे रेकैकाइल 1.9.2+ को संगत बनाने का पसंदीदा तरीका क्या है?

उत्तर

139

यह एक "सुरक्षा" जोखिम माना गया।

आप पूर्ण पथ

File.expand_path(__FILE__) et al 

या

require './filename' (ironically). 

कर का उपयोग करके या

require_relative 'filename' 

का उपयोग कर या जोड़कर उसके चारों ओर प्राप्त कर सकते हैं एक निर्देशिका "शामिल हैं"

ruby -I . ... 
012,

या वही, irb का उपयोग कर;

$irb -I . 
+26

मैं 'require_relative' का उपयोग कर को समाप्त। धन्यवाद। –

+11

क्या यह अधिकांश यूनिक्स के समान है जिसमें निष्पादन योग्य चलाने के लिए पथ में वर्तमान निर्देशिका शामिल नहीं है? –

+1

@Andrew हाँ मुझे ऐसा लगता है। – rogerdpack

34
वहाँ

दो कारणों से है:

  • मजबूती और
  • सुरक्षा

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

+5

मुझे नहीं लगता कि दो फाइलें एक दूसरे के सापेक्ष एक ही स्थान पर लागू हो रही हैं, यह एक बुरी आवश्यकता है। यदि यह सत्य थे, तो हमारे पास निर्देशिकाओं के लिए कोई उपयोग नहीं होगा। –

+4

@ जॉन फेमिनेला: फ़ाइलों को एक दूसरे के सापेक्ष पथ में डालने के साथ क्या करना है? प्रश्न उन्हें '.' के संबंध में रखने के बारे में है, यानी वर्तमान कार्यशील निर्देशिका। यदि उपयोगकर्ता एक अलग निर्देशिका में 'cd' है, तो वर्तमान कार्यशील निर्देशिका बदलती है, और अब आपको * पूरी तरह से * अलग-अलग फ़ाइलों की आवश्यकता होती है, इस पर निर्भर करता है कि जब उपयोगकर्ता आपकी स्क्रिप्ट कहता है तो उस निर्देशिका के आधार पर क्या होता है। मुझे नहीं लगता कि यह एक अच्छा विचार है। –

+0

तो एक सभ्य इंटरफ़ेस बनाए रखने के लिए, आपको यह करना चाहिए? '$: << File.dirname (__ फ़ाइल __)' –

6

'।' यूनिक्स दुनिया में आपके रास्ते में लंबे समय से एक बुरी चीज माना गया है (उदाहरण के लिए, http://www.faqs.org/faqs/unix-faq/faq/part2/section-13.html)। मुझे लगता है कि रूबी लोगों को ऐसा करने के ज्ञान के बारे में राजी किया गया है।

3

जैसा कि जोर्ग डब्ल्यू मिट्टाग ने बताया, मुझे लगता है कि आप जो उपयोग करना चाहते हैं वह require_relative है, इसलिए आपको जिस फ़ाइल की आवश्यकता है वह require घोषणा की स्रोत फ़ाइल से संबंधित है और वर्तमान कामकाजी डीआईआर नहीं है।

आपका निर्भरता अपने रेक निर्माण फ़ाइल के अनुरूप होना चाहिए।

16

जैसा कि अन्य उत्तर देते हैं, यह एक सुरक्षा जोखिम है क्योंकि आपके लोड पथ में . वर्तमान कार्यशील निर्देशिका Dir.pwd को संदर्भित करता है, वर्तमान फ़ाइल लोड होने की निर्देशिका नहीं। तो जो कोई भी आपकी स्क्रिप्ट निष्पादित कर रहा है, वह इसे cd अन्य निर्देशिका में बदल सकता है। अच्छा नही!

मैं पूर्ण पथ एक विकल्प के रूप __FILE__ से निर्मित उपयोग कर रहे हैं।

require File.expand_path(File.join(File.dirname(__FILE__), 'filename')) 

require_relative के विपरीत, इस रूबी 1.8.7 के साथ पिछड़े संगत है।

+4

यह भिन्नता भी है (जिसे मैं व्यक्तिगत रूप से अधिक पठनीय पाते हैं): 'पथनाम.न्यू (__ फ़ाइल __) की आवश्यकता है। Dirname +' filename ' –

3

मुझे यह एक उलझन में बदलाव होने के लिए मिला जब तक कि मुझे कुछ चीजों का एहसास नहीं हुआ।

आप अपने .profile (यूनिक्स) में RUBYLIB सेट और जो आपने पहले जीवन के साथ पर जा सकते हैं:

export RUBYLIB="."

लेकिन जैसा कि ऊपर उल्लेख, यह लंबे समय असुरक्षित ऐसा करने के लिए विचार किया गया है।

अधिकांश मामलों के लिए आप अपनी रूबी स्क्रिप्ट को प्रीपेन्ड 'के साथ कॉल करके समस्याओं से बच सकते हैं। जैसे ./scripts/server।

8

उपयोग require_relative 'file_to_require'

अपने कोड में फेंक इस 1.8.7 में require_relative काम करने के लिए:

unless Kernel.respond_to?(:require_relative) 
    module Kernel 
    def require_relative(path) 
     require File.join(File.dirname(caller.first), path.to_str) 
    end 
    end 
end