Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Ruby

रूबी मॉड्यूल को नेस्ट करते समय इन जालों से बचें

मॉड्यूल (और कक्षाएं) नेस्टेड होने के लिए हैं। कोड के टुकड़े जैसे ActiveRecord::RecordNotFound इतने सामान्य हैं कि हम उनके बारे में दो बार नहीं सोचते। लेकिन रूबी के घोंसले के कार्यान्वयन के भीतर दफन - और रेल 'ऑटोलैड सिस्टम - कुछ जाल हैं जो आपके कोड को अजीब और अद्भुत तरीकों से विफल कर सकते हैं। इस पोस्ट में, हम इन जालों की उत्पत्ति और आप इनसे कैसे बच सकते हैं, इस पर चर्चा करेंगे।

एक स्थिरांक क्या है?

यह पोस्ट मॉड्यूल के बारे में है, लेकिन उन्हें समझने के लिए हमें स्थिरांक को समझने की जरूरत है। अधिकांश भाषाओं में, स्थिरांक का उपयोग केवल थोड़े से डेटा को संग्रहीत करने के लिए किया जाता है, जैसे नीचे दिए गए उदाहरण में:

# These are simple constants
MAX_RETRIES = 5
DEFAULT_LANGUAGE = "en"

लेकिन रूबी में, कक्षाएं और मॉड्यूल भी स्थिरांक हैं। मैंने इसे प्रदर्शित करने के लिए एक छोटा सा उदाहरण लिखा है। नीचे मॉड्यूल में तीन स्थिरांक हैं:एक संख्या, एक वर्ग और एक नेस्टेड मॉड्यूल। जब आप किसी नेस्टेड क्लास या मॉड्यूल को एक्सेस करते हैं, तो माणिक इसे उन्हीं नियमों का उपयोग करके ढूंढता है, जिनका उपयोग वह एक साधारण संख्यात्मक स्थिरांक के साथ करेगा।

module MyModule
  MY_FAVORITE_NUMBER = 7

  # Classes are constants
  class MyClass
  end

  # So are modules
  module MyEmbeddedModule
  end
end

puts MyModule.constants.inspect # => [:MY_FAVORITE_NUMBER, :MyClass, :MyEmbeddedModule]

अक्सर, मॉड्यूल के पास अपने माता-पिता में परिभाषित स्थिरांक तक पहुंच होती है। इसलिए आप इस तरह कोड लिख सकते हैं:

module X
  MARCO = "polo"
  module Y
    def self.n 
      puts MARCO
    end
  end
end

X::Y.n() # => "polo"

लेकिन आप गलत होंगे यदि आपको लगता है कि यह माता-पिता/बच्चे का संबंध था जो Y को X के निरंतर MARCO तक पहुंचने की अनुमति देता है।

एक आम समस्या

यदि हम ऊपर दिए गए कोड को थोड़ा अलग तरीके से फिर से लिखते हैं, तो कुछ आश्चर्यजनक होता है। Y अब X::MARCO तक नहीं पहुंच सकता। यहाँ क्या हो रहा है?

module A
  MARCO = "polo"
end

module A::B
  def self.n 
    puts MARCO  # => uninitialized constant A::B::MARCO (NameError)
  end
end

A::B.n()

यह पता चला है कि बच्चे द्वारा माता-पिता के स्थिरांक की "विरासत" माता-पिता/बाल संबंधों के कारण नहीं है। यह शाब्दिक है। इसका मतलब है कि यह आपके कोड की संरचना पर आधारित है, न कि आपके कोड द्वारा बनाए जा रहे ऑब्जेक्ट की संरचना पर।

नेस्टिंग की जांच करना

यदि आप इस बात की गहरी समझ प्राप्त करना चाहते हैं कि रूबी नेस्टेड स्थिरांक की खोज कैसे करती है, तो यह Module.nesting को देखने लायक है। समारोह।

यह फ़ंक्शन ऑब्जेक्ट्स की एक सरणी देता है जो किसी दिए गए दायरे में स्थिरांक के लिए "खोज पथ" बनाते हैं। आइए अपने पिछले उदाहरणों के लिए नेस्टिंग की जांच करें।

हमारे पहले उदाहरण में, हम देखते हैं कि नेस्टिंग [A::B, A] . है . इसका मतलब यह है कि यदि हम निरंतर मार्को का उपयोग करते हैं, तो रूबी इसे पहले A::B में ढूंढेगी। , और फिर A . में ।

module A
  MARCO = "polo"
  module B
    def self.n 
      puts Module.nesting.inspect  # => [A::B, A]
      puts MARCO # => "polo"
    end
  end
end

दूसरे उदाहरण में, हम देखते हैं कि नेस्टिंग में केवल A::B . शामिल है , नहीं A . भले ही B A . का "बच्चा" है , जिस तरह से मैंने कोड लिखा है वह उन्हें नेस्टेड के रूप में नहीं दिखाता है, इसलिए इस उद्देश्य के लिए वे भी नहीं हो सकते हैं।

module A
  MARCO = "polo"
end

module A::B
  def self.n 
    puts Module.nesting.inspect  # => [A::B]
    puts MARCO # => uninitialized constant A::B::MARCO (NameError)
  end
end

रेल ऑटोलोड जटिलताएं

क्या आपने कभी गौर किया है कि जब आप रेल का उपयोग करते हैं तो आपको फाइलों को शामिल करने की आवश्यकता नहीं होती है? यदि आप किसी मॉडल का उपयोग करना चाहते हैं, तो आप बस उसका उपयोग करें।

यह संभव है क्योंकि रेल एक ऑटोलोड सिस्टम लागू करता है। यह Module.const_missing . का उपयोग करता है यह पता लगाने के लिए कि जब आप एक स्थिरांक को संदर्भित करने का प्रयास करते हैं जिसे लोड नहीं किया गया है। इसके बाद यह उन फ़ाइलों को लोड करता है जो मानते हैं कि इसमें स्थिरांक होना चाहिए। यह ज्यादातर समय काम करता है, लेकिन एक पकड़ है।

रेल मानता है कि एक मॉड्यूल में हमेशा सबसे बड़ा संभव घोंसला होता है। यह मानता है कि मॉड्यूल A::B::C में [A::B::C, A::B, A] का नेस्टिंग होगा। . अगर ऐसा नहीं होता है तो आपको अप्रत्याशित व्यवहार मिलेगा।

नीचे दिए गए कोड में, मॉड्यूल बी A::MARCO . तक पहुंचने में सक्षम नहीं होना चाहिए . सामान्य रूबी में, यह सक्षम नहीं होगा क्योंकि इसका घोंसला [ए ::बी] है। तो आपको अपवाद मिलना चाहिए। लेकिन रेल 'ऑटोलैड अपवाद नहीं फेंकता है। इसके बजाय, यह A::MARCO . लौटाता है ।

# a.rb
module A
  MARCO = "polo"
end

# a/b.rb
module A::B
  def self.n 
    puts MARCO # => "polo"
  end
end

# some_controller.rb
A::B.n()

निष्कर्ष?

यह सब बहुत सोचने वाली बात है। जहां संभव हो मैं सोचने से बचना पसंद करता हूं, इसलिए मैं मॉड्यूल से दूर रहने की कोशिश करता हूं A::B वाक्य - विन्यास। मैं ऐसे मामले के बारे में नहीं सोच सकता जहां मैं जानबूझकर मॉड्यूल घोंसले में हेरफेर करना चाहता हूं। यदि आप किसी के बारे में जानते हैं, तो मुझे उनके बारे में सुनना अच्छा लगेगा!


  1. रूबी केस स्टेटमेंट के कई उपयोग

    जब भी आपको कुछ if / elsif . का उपयोग करने की आवश्यकता हो आप इसके बजाय रूबी केस स्टेटमेंट का उपयोग करने पर विचार कर सकते हैं। इस पोस्ट में, आप कुछ अलग उपयोग के मामलों के बारे में जानेंगे और यह सब वास्तव में हुड के तहत कैसे काम करता है। नोट:अन्य प्रोग्रामिंग भाषाओं में इसे स्विच . के रूप में जाना

  1. Google पर इन 12 चीजों को खोजते समय सावधान रहें

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

  1. इन Windows रखरखाव गलतियों को करने से बचें

    प्रौद्योगिकी में प्रगति के साथ, उपयोगकर्ताओं ने अपने विंडोज कंप्यूटरों को बनाए रखने के मूल तरीके को समझ लिया है और इसे स्वस्थ रखने के लिए समय-समय पर इसे साफ करते हैं। हालाँकि, समय के साथ OS बहुत बदल गया है, विशेष रूप से Windows 10, इसलिए इसके रखरखाव के तरीके भी हैं। लेकिन उपयोगकर्ताओं को इसके बारे म