रूबी में आवश्यकता और संबंध के बीच अंतर क्या है?


302

require_relativeऔर requireरूबी में क्या अंतर है ?


9
1.9.2 से पहले आवश्यकता के लिए कोई आवश्यकता नहीं थी_संबंधी, क्योंकि स्क्रिप्ट की वर्तमान निर्देशिका थी $:। देखें stackoverflow.com/questions/2900370
Nakilon

1
requirement_relative के लिए विशेष रूप से कॉल करने वाली फ़ाइल के सापेक्ष इंगित की गई फ़ाइल की आवश्यकता होती है। आवश्यकता $ LOAD_PATH में शामिल एक फ़ाइल की आवश्यकता है।
डोनाटो

मतभेद => के बारे में उपयोगी लेख medium.com/@ellishim/...
अहमद hamdy

जवाबों:


298

बस डॉक्स को देखें :

require_relativerequireआप एक फ़ाइल को लोड करने की अनुमति देकर बिलिन विधि का अनुपालन करते हैं जो कि require_relativeकथन वाली फ़ाइल के सापेक्ष है ।

उदाहरण के लिए, यदि आपके पास "परीक्षण" निर्देशिका में इकाई परीक्षण कक्षाएं हैं, और परीक्षण "परीक्षण / डेटा" निर्देशिका के तहत उनके लिए डेटा है, तो आप एक परीक्षण मामले में इस तरह की रेखा का उपयोग कर सकते हैं:

require_relative "data/customer_data_1"

28
क्या आपस में require './file.rb'और कोई फर्क है require_relative 'file.rb'?
सिरो सेंटिल्ली 郝海东 i iro i 法轮功 '25

69
@CiroSantilli हाँ। require_relativeआपको "एक फ़ाइल लोड करने की अनुमति देता है जो कि कथन वाली फ़ाइल के सापेक्ष हैrequire_relative "। के साथ require, ./एक पथ इंगित करता है जो आपकी वर्तमान कार्यशील निर्देशिका के सापेक्ष है।
अजादि32

16
मुझे लगता है कि यह नोट करना अधिक महत्वपूर्ण है कि require strहमेशा $ LOAD_PATH में निर्देशिकाओं के माध्यम से खोज करेंगे। require_relativeजब आपको लोड करने की आवश्यकता होती है, तो आपको उस फ़ाइल के सापेक्ष कहीं मौजूद होना चाहिए जो लोडिंग के लिए कॉल करता है। require"बाहरी" निर्भरता के लिए आरक्षित ।
रथबेड

97

require_relative का एक सुविधाजनक सबसेट है require

require_relative('path')

बराबर है:

require(File.expand_path('path', File.dirname(__FILE__)))

अगर __FILE__परिभाषित किया गया है, या यह LoadErrorअन्यथा उठता है।

यह बताता है कि:

  • require_relative 'a'और वर्तमान फ़ाइल केrequire_relative './a' सापेक्ष आवश्यक है ( )।__FILE__

    यह वही है जो आप अपने पुस्तकालय के अंदर आवश्यकता होने पर उपयोग करना चाहते हैं, क्योंकि आप नहीं चाहते कि परिणाम कॉलर की वर्तमान निर्देशिका पर निर्भर हो।

  • eval('require_relative("a.rb")')उठाता है LoadErrorक्योंकि __FILE__अंदर परिभाषित नहीं है eval

    यही कारण है कि आप require_relativeRSpec परीक्षणों में उपयोग नहीं कर सकते हैं , जो evalएड प्राप्त करते हैं ।

निम्नलिखित ऑपरेशन केवल इसके साथ ही संभव हैं require:

  • require './a.rb'वर्तमान निर्देशिका के सापेक्ष आवश्यकता होती है

  • require 'a.rb'$LOAD_PATHआवश्यकता के लिए खोज पथ ( ) का उपयोग करता है। यह वर्तमान निर्देशिका या पथ के सापेक्ष फाइलें नहीं खोजता है।

    यह संभव नहीं है require_relativeक्योंकि दस्तावेज़ का कहना है कि मार्ग खोज ही होता है जब "फ़ाइल नाम एक निरपेक्ष पथ के लिए हल नहीं होती है" (के साथ शुरू होता है यानी /या ./या ../) है, जो हमेशा के लिए मामला है File.expand_path

निम्नलिखित ऑपरेशन दोनों के साथ संभव है, लेकिन आप requireइसे कम और अधिक कुशल बनाने के लिए उपयोग करना चाहेंगे :

  • require '/a.rb'और require_relative '/a.rb'दोनों को परम मार्ग की आवश्यकता है।

स्रोत को पढ़ना

जब डॉक्स स्पष्ट नहीं होते हैं, तो मैं सुझाव देता हूं कि आप स्रोतों (डॉक्स में स्रोत को टॉगल करें) पर एक नज़र डालें। कुछ मामलों में, यह समझने में मदद करता है कि क्या चल रहा है।

आवश्यकता होती है:

VALUE rb_f_require(VALUE obj, VALUE fname) {
  return rb_require_safe(fname, rb_safe_level());
}

require_relative:

VALUE rb_f_require_relative(VALUE obj, VALUE fname) {
    VALUE base = rb_current_realfilepath();
    if (NIL_P(base)) {
        rb_loaderror("cannot infer basepath");
    }
    base = rb_file_dirname(base);
    return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
}

यह हमें यह निष्कर्ष निकालने की अनुमति देता है

require_relative('path')

के समान है:

require(File.expand_path('path', File.dirname(__FILE__)))

चूंकि:

rb_file_absolute_path   =~ File.expand_path
rb_file_dirname1        =~ File.dirname
rb_current_realfilepath =~ __FILE__

74

रूबी एपीआई से :

requirement_relative कंप्लेंट्स में buildin मेथड की आवश्यकता होती है जो आपको एक फाइल लोड करने की अनुमति देता है जो कि आवश्यकता के अनुरूप फाइल के सापेक्ष होती है।

जब आप किसी फ़ाइल को लोड करने की आवश्यकता का उपयोग करते हैं, तो आप आमतौर पर कार्यक्षमता को एक्सेस कर रहे होते हैं जो आपके सिस्टम में ठीक से स्थापित किया गया है, और सुलभ बनाया गया है। आवश्यकता परियोजना के कोड के भीतर फ़ाइलों को लोड करने के लिए एक अच्छा समाधान प्रदान नहीं करता है। यह एक विकास चरण के दौरान उपयोगी हो सकता है, परीक्षण डेटा तक पहुंचने के लिए, या यहां तक ​​कि उन फ़ाइलों तक पहुंचने के लिए जो किसी प्रोजेक्ट के अंदर "लॉक" हैं, न कि बाहरी उपयोग के लिए।

उदाहरण के लिए, यदि आपके पास "परीक्षण" निर्देशिका में इकाई परीक्षण कक्षाएं हैं, और परीक्षण "परीक्षण / डेटा" निर्देशिका के तहत उनके लिए डेटा है, तो आप एक परीक्षण मामले में इस तरह की रेखा का उपयोग कर सकते हैं:

require_relative "data/customer_data_1" 

चूंकि न तो "परीक्षण" और न ही "परीक्षण / डेटा" रूबी के पुस्तकालय पथ (और अच्छे कारण के लिए) में होने की संभावना है, एक सामान्य आवश्यकता उन्हें नहीं मिलेगी। requirement_relative इस विशेष समस्या के लिए एक अच्छा समाधान है।

आप अपने द्वारा लोड की जा रही फ़ाइल के एक्सटेंशन (.rb या .so) को शामिल या छोड़ सकते हैं।

पथ को to_str का जवाब देना चाहिए।

आप http://extensions.rubyforge.org/rdoc/classes/Kernel.html पर प्रलेखन पा सकते हैं


50

सारांश

requireस्थापित रत्नों के लिए उपयोग करें

require_relativeस्थानीय फ़ाइलों के लिए उपयोग करें

require$LOAD_PATHफ़ाइलों को खोजने के लिए अपने का उपयोग करता है ।
require_relativeस्टेटमेंट का उपयोग करके फ़ाइल के वर्तमान स्थान का उपयोग करता है


की आवश्यकता होती है

gem install [package]उस कार्यक्षमता के लिए आपके सिस्टम पर कहीं एक पैकेज स्थापित होने (जैसे ) पर निर्भर होने की आवश्यकता होती है।

जब requireआप वर्तमान निर्देशिका में फ़ाइल के लिए " " प्रारूप का उपयोग कर सकते हैं ./, उदाहरण के लिए, require "./my_file"लेकिन यह एक सामान्य या अनुशंसित अभ्यास नहीं है और आपको require_relativeइसके बजाय उपयोग करना चाहिए ।

require_relative

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

require_relative '../../../filename'

(3 डायरेक्टरी लेवल तक) फाइल सिस्टम के भीतर क्योंकि यह अनावश्यक और भंगुर निर्भरता पैदा करता है। हालाँकि कुछ मामलों में यदि आप पहले से ही एक डायरेक्टरी ट्री के भीतर 'डीप' हैं तो एक और डायरेक्टरी ट्री ब्रांच "अप एंड डाउन" आवश्यक हो सकती है। अधिक सरल रूप से, इस रिपॉजिटरी के बाहर की फाइलों के लिए requ_relative का उपयोग न करें (यह मानते हुए कि आप git का उपयोग कर रहे हैं जो इस बिंदु पर काफी हद तक एक वास्तविक मानक है, 2018 के अंत में)।

ध्यान दें कि आवश्यकता के साथ फ़ाइलrequire_relative की वर्तमान निर्देशिका का उपयोग करना आवश्यक है (इसलिए जरूरी नहीं कि आपकी वर्तमान निर्देशिका जो आप कमांड का उपयोग कर रहे हैं)। यह require_relativeपथ को "स्थिर" रखता है क्योंकि यह हमेशा उसी तरह से आवश्यक फ़ाइल के सापेक्ष होता है।


27

शीर्ष उत्तर सही हैं, लेकिन गहराई से तकनीकी हैं। रूबी के लिए नए लोगों के लिए:

  • require_relative आपके द्वारा लिखी गई किसी अन्य फ़ाइल से कोड लाने के लिए सबसे अधिक संभावना होगी।

उदाहरण के लिए, यदि आपके पास डेटा है ~/my-project/data.rbऔर आप उसे इसमें शामिल करना चाहते हैं ~/my-project/solution.rb? में solution.rbआप जोड़ना होगा require_relative 'data'

यह नोट करना महत्वपूर्ण है कि इन फ़ाइलों को एक ही निर्देशिका में होने की आवश्यकता नहीं है। require_relative '../../folder1/folder2/data'भी मान्य है।

  • require किसी पुस्तकालय में किसी अन्य व्यक्ति द्वारा लिखे गए कोड को लाने के लिए सबसे अधिक संभावना होगी।

उदाहरण के लिए, यदि आप active_supportपुस्तकालय में दिए गए सहायक कार्यों में से किसी एक का उपयोग करना चाहते हैं, तो क्या होगा ? आपको मणि को gem install activesupportफिर फ़ाइल में स्थापित करना होगा require 'active_support'

require 'active_support/all'
"FooBar".underscore

अलग तरह से कहा--

  • require_relative विशेष रूप से कॉल करने वाली फ़ाइल के सापेक्ष इंगित की गई फ़ाइल की आवश्यकता होती है।

  • requireमें शामिल एक फ़ाइल की आवश्यकता है $LOAD_PATH


3
मैं इस उत्तर को कैसे वोट कर सकता हूं और इसे शीर्ष तक पहुंचा सकता हूं, इसलिए इस प्रश्न पृष्ठ के प्रत्येक आगंतुक को अपने दिमाग को तोड़े बिना एक स्पष्ट और समझने योग्य उत्तर मिलेगा?
TiredOfProgramming

16

मैंने अभी देखा कि RSpec के कोड में require_relativeO (1) स्थिर और requireO (N) रैखिक होने पर कुछ टिप्पणी है । तो शायद अंतर यह है कि require_relativeपसंदीदा की तुलना में अधिक है require


1
दिलचस्प। मैं एक गति तुलना पर जानकारी की तलाश में यहाँ उतरा। मेरी सोच यह require_relativeतेज़ थी क्योंकि लोडर को फ़ाइल की तलाश में लोड पथ को पार नहीं करना पड़ता है। अनिवार्य रूप से, require_relativeएक सीधा लिंक प्रदान करता है।
क्लिंट पाचल

आवश्यकता की गति और RSpec चैंज के बारे में प्रारंभिक असंतोष ।
क्लिंट पाचल

1

मैं यह जोड़ना चाहता हूं कि विंडोज का उपयोग करते समय आप उपयोग कर सकते हैं require './1.rb'यदि स्क्रिप्ट स्थानीय या एक मैप्ड नेटवर्क ड्राइव से चलती है, लेकिन जब यूएनसी \\servername\sharename\folderपथ से चलाया जाता है तो आपको उपयोग करने की आवश्यकता होती है require_relative './1.rb'

मैं अन्य कारणों से चर्चा में नहीं आता।


मुझे पता है कि कैसे आप लोड करना चाहता था require_relativeफ़ाइल आप कृपया इस पर एक विचार फेंक कर सके stackoverflow.com/questions/43487784/...
Emjey
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.