माणिक में निर्देशिका से सभी फ़ाइलों की आवश्यकता के लिए सबसे अच्छा तरीका है?


351

माणिक में डायरेक्टरी से सभी फाइलों की आवश्यकता का सबसे अच्छा तरीका क्या है?


आप निर्देशिका के समान नाम के साथ एक फ़ाइल बना सकते हैं और इसके लिए सभी फ़ाइलों की आवश्यकता होती है। RSpec ऐसा करता है।
पेड्रोमानोएल

जवाबों:


462

कैसा रहेगा:

Dir["/path/to/directory/*.rb"].each {|file| require file }

18
पिकैक्स के अनुसार, .rb एक्सटेंशन वैकल्पिक है। तकनीकी रूप से इसका अर्थ बदल जाता है: "foo.rb 'के लिए" foo.rb की आवश्यकता होती है, जबकि "foo.rb की आवश्यकता होती है" के लिए foo.rb, foo.so या foo.dll की आवश्यकता हो सकती है।
सैम स्टोक्स

28
विस्तार को न छीनने के लिए एक सूक्ष्म गोटा है। यदि कोड कॉल के कुछ अन्य भाग में 'foo' की आवश्यकता होती है, तो माणिक फिर से उसी फ़ाइल को लोड करेगा, जिससे नकली त्रुटियां हो सकती हैं। मैंने अपना स्वयं का उत्तर जोड़ा, जो बताता है कि और विस्तार कैसे छीनता है।
पीट हॉजसन

4
@ पता, क्या यह अभी भी सच है? देखें रेने की टिप्पणी नीचे।
एंड्रेस रिओप्रियो

5
यह स्पष्ट हो सकता है, लेकिन यह ध्यान देने योग्य है कि .rb को छोड़ने से dir में किसी भी गैर-.rb फ़ाइलों की आवश्यकता होगी, जो संभव नहीं है।
user2398029

10
@ पेटेहोडगसन का सुझाव गलत है। रूबी विस्तार requireकी उपस्थिति या अनुपस्थिति से भ्रमित नहीं है .rb। एमआरआई 1.8.7-p374, 2.1.5 और 2.2.0 पर परीक्षण किया गया। यह शहरी किंवदंती रेल से आती है, जहां "चतुर" ऑटोलोडिंग ने पुराने संस्करणों में वर्णित व्यवहार का प्रदर्शन किया (और अभी भी इसे प्रदर्शित कर सकता है)।
sheldonh

345

यदि यह फाइल के सापेक्ष एक निर्देशिका है जो आवश्यक है (उदाहरण के लिए आप सभी फाइलों को लोड करना चाहते हैं):

Dir[File.dirname(__FILE__) + '/lib/*.rb'].each {|file| require file }

संपादित करें: नीचे दी गई टिप्पणियों के आधार पर, एक अद्यतन संस्करण:

Dir[File.join(__dir__, 'lib', '*.rb')].each { |file| require file }

14
आप इस तरह से सभी बच्चे निर्देशिकाओं को भी जोड़ सकते हैंDir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
jspooner

62
यह शायद आगे / पिछड़े स्लेश के बारे में धारणा बनाने के बजाय File.join का उपयोग करने के लिए सुरक्षित है:Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
क्रिस

6
आवश्यकता भी
है_संबंधी

30
यदि आप> = रूबी 2.0 का उपयोग कर रहे हैं, तो आप __dir__इसके स्थान पर उपयोग कर सकते हैं File.dirname(__FILE__)
क्रिश्चियन बैंकेस्टर

3
@maasha require_relativeएक निर्देशिका में सभी फ़ाइलों की आवश्यकता के लिए आप कैसे उपयोग करते हैं ?
डेविड मोल्स

101

आवश्यक रत्न की कोशिश करें:

  1. http://github.com/jarmo/require_all
  2. https://rubygems.org/gems/require_all

यह आपको बस देता है:

require_all 'path/to/directory'

मुझे अपने सभी ActiveRecord मॉडल शामिल करने की आवश्यकता थी, requirement_all मणि ने सभी निर्भरताओं का पता लगाया और उन्हें पूरी तरह से आवश्यक किया। धन्यवाद!
panupan

2
@panupan बस इस बात से अवगत रहें कि require_allचक्रीय निर्भरता समाधान आपके स्रोत कोड में एक समस्या के आसपास काम करता है: आपके पास रूबी स्रोत फाइलें हैं, जिन्हें उनकी निर्भरता की आवश्यकता नहीं है। यह स्केलपेल लोडिंग पर दरवाजे को बंद कर देता है, आपको सभी-या-कुछ लोड करने के लिए प्रतिबद्ध करता है। यह छोटे पुस्तकालयों में कोई समस्या नहीं है, लेकिन यह एक ऐसा निर्णय है जिसे आपको सचेत रूप से करना चाहिए।
शेल्डन

आपके एप्लिकेशन को रत्नों के साथ ब्लोट करने का कोई मतलब नहीं है कि आप कोड की एक पंक्ति के साथ बदल सकते हैं। यह आपके ऐप के लोड समय को बढ़ाता है और लंबी अवधि में अधिक बग को प्रेरित करता है।
पेरे जोन मार्टोरेल

52
Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file| 
  require File.basename(file, File.extname(file))
end

यदि आप एक्सटेंशन नहीं छीनते हैं तो आप एक ही फाइल को दो बार समाप्त कर सकते हैं (माणिक को यह महसूस नहीं होगा कि "फू" और "फू.बीबी" एक ही फाइल हैं)। एक ही फ़ाइल को दो बार आवश्यक करने से गंभीर चेतावनी हो सकती है (उदाहरण के लिए "चेतावनी: पहले से ही आरंभिक स्थिर")।


11
क्या वास्तव में यह मामला है? दस्तावेज़ीकरण कहता है: एक सुविधा लोड नहीं होगी यदि उसका नाम पहले से ही $ में दिखाई देता है "। फ़ाइल का नाम एक पूर्ण पथ में परिवर्तित हो जाता है, इसलिए" a 'की आवश्यकता होती है; आवश्यकता './a' 'दो बार a.rb लोड नहीं करेगा। ruby-doc.org/core/classes/Kernel.html#M001418
डेरेक

13
मेरे परीक्षण से पता चलता है कि डेरेक ने कहा: बस एक बार require "foo.rb"; require "foo";लोड होगा foo.rb
रेने सारसो 14

@ PeteHodgson- क्या आप इसे वापस कर सकते हैं?
यारिन

4
नहीं। रूबी विस्तार requireकी उपस्थिति या अनुपस्थिति से भ्रमित नहीं है .rb। एमआरआई 1.8.7-p374, 2.1.5 और 2.2.0 पर परीक्षण किया गया। यह शहरी किंवदंती रेल से आती है, जहां "चतुर" ऑटोलोइंग ने पुराने संस्करणों में वर्णित व्यवहार का प्रदर्शन किया (और अभी भी इसे प्रदर्शित कर सकता है)।
sheldonh

45
Dir.glob(File.join('path', '**', '*.rb'), &method(:require))

या वैकल्पिक रूप से, यदि आप विशिष्ट फ़ोल्डरों को लोड करने के लिए फ़ाइलों को स्कोप करना चाहते हैं:

Dir.glob(File.join('path', '{folder1,folder2}', '**', '*.rb'), &method(:require))

स्पष्टीकरण:

Dir.glob तर्क के रूप में एक ब्लॉक लेता है।

विधि (: की आवश्यकता है) की आवश्यकता विधि वापस आ जाएगी।

और विधि (: आवश्यकता) विधि को एक ब्लॉक में बदल देगी।


2
यह कुछ सुंदर कोड है। मैं प्यार करता हूँ कि कैसे कोई दृश्य ब्लॉक नहीं हैं।
नैट सीमर

1
Dir.glob( File.join( File.dirname(__FILE__), '{lib,addons}', 'subfolder', '**', '*.rb' ), &method(:require) )प्लेटफ़ॉर्म (जैसे '/' या '\') पर निर्भरता को समाप्त करता है। अच्छा काम करता है। धन्यवाद।
इवान ब्लैक

30

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

$ irb
irb(main):001:0> require 'test'
=> true
irb(main):002:0> require './test'
=> true
irb(main):003:0> require './test.rb'
=> false
irb(main):004:0> require 'test'
=> false

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

इसके बजाय, हम एक निर्देशिका को लोड पथ में जोड़ते हैं और फिर प्रत्येक * .rb फ़ाइल के बेसनेम की आवश्यकता होती है।

dir = "/path/to/directory"
$LOAD_PATH.unshift(dir)
Dir[File.join(dir, "*.rb")].each {|file| require File.basename(file) }

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

Dir["/path/to/directory/*.rb"].each {|file| load file }

14

कुछ जवाबों की तरह, पथ का उपयोग करने के बजाय, मैं उपयोग करता हूं File.expand_path:

Dir[File.expand_path('importers/*.rb', File.dirname(__FILE__))].each do |file|
  require file
end

अपडेट करें:

उपयोग करने के बजाय File.dirnameआप निम्नलिखित कार्य कर सकते हैं:

Dir[File.expand_path('../importers/*.rb', __FILE__)].each do |file|
  require file
end

कहाँ ..का फ़ाइल नाम छीनता है __FILE__


यह निश्चित रूप से जाने का रास्ता लगता है, और अधिकांश उत्तर की तारीख तक, बाकी के सभी प्रयास करने के बाद, +1 के लिएFile.expand_path
SuckerForMayhem

मैं निश्चित रूप से स्वीकार किए गए इस जवाब को पसंद करता हूं। Rails.root.joinयदि आप रेल में हैं तो विभिन्न उत्तर भी काम करते हैं।
nizifnab 23

14
Dir[File.join(__dir__, "/app/**/*.rb")].each do |file|
  require file
end

यह आपके स्थानीय मशीन और एक रिमोट (लाइक हेरोकू) पर पुनरावर्ती रूप से काम करेगा, जो सापेक्ष रास्तों का उपयोग नहीं करता है।


8

रेल में, आप कर सकते हैं:

Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }

अपडेट: स्लैश को हटाने के लिए @ जिग्नेश गोहल के सुझाव के साथ सही किया गया।


चूंकि Rails.rootएक Pathnameउदाहरण है, आप इसे किसी भी रूबी वातावरण में कर सकते हैं, न केवल रेल (एनबी Rails.root.join('lib/ext/*.rb')थोड़ा पढ़ता है)
DMKE

सिफारिश के लिए धन्यवाद; मैंने आपकी टिप्पणी को शामिल करने के लिए संपादन किया।
दान कोन

Rails.root के अंतर्गत उप-निर्देशिकाओं के लिए फॉरवर्ड स्लैश (/) का उपयोग करना, उदाहरण के Rails.root.join('/lib')लिए सही मार्ग उत्पन्न नहीं करता है। मुझे यह सही ढंग से काम करने के लिए मिला:Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
जिग्नेश गोहेल

@ जिग्नेश गोहेल ने सुझाव देते हुए स्लैश को हटा दिया, धन्यवाद।
दान कोन

3

मुझे पार्टी में कुछ साल हो गए हैं, लेकिन मुझे इस तरह का एक-लाइन समाधान पसंद है जो मुझे ऐप / कार्यकर्ताओं / चिंताओं में सब कुछ शामिल करने के लिए रेल मिलता था:

Dir[ Rails.root.join *%w(app workers concerns *) ].each{ |f| require f }


-2

और किस बारे में require_relative *Dir['relative path']:?


1
रिश्तेदार को कई फाइलें लेने की आवश्यकता नहीं है: ruby-doc.org/core-2.1.2/Kernel.html#method-i-require_relative
fabriciofreitag

ठीक है, लेकिन मेरे उदाहरण में यह नहीं है। '*' परिवर्तन 1 को बदलता है। यह कई कॉल के रूप में कार्य करता है।
अलेक्जेंडर

1
'*' 1 के लिए परिवर्तन करता है - क्या आप इसके साथ क्या मतलब है? require_relative *Dir['*.rb']काम, अगर केवल एक रूबी-स्क्रिप्ट है। लेकिन अगर एक से अधिक गहरे लाल रंग का लिपियों पाए जाते हैं, आप प्राप्तrequire_relative': wrong number of arguments (4 for 1) (ArgumentError)
नूट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.