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

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

विकिपीडिया के अनुसार, ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग (OOP) "ऑब्जेक्ट्स" की अवधारणा पर आधारित एक प्रोग्रामिंग पैराडाइम है, जिसमें डेटा और कोड दोनों हो सकते हैं: डेटा फील्ड्स के रूप में (जिन्हें अक्सर एट्रिब्यूट्स या प्रॉपर्टीज के रूप में जाना जाता है) और कोड प्रोसीजर के रूप में (जिन्हें अक्सर मेथड्स के रूप में जाना जाता है)।

Ruby एक शुद्ध ऑब्जेक्ट-ओरिएंटेड भाषा है, जिसका अर्थ है कि Ruby भाषा में, सब कुछ एक ऑब्जेक्ट है। ये ऑब्जेक्ट्स, चाहे वे स्ट्रिंग्स, नंबर्स, क्लासेस, मॉड्यूल्स आदि हों, द ऑब्जेक्ट मॉडल नामक एक सिस्टम में काम करते हैं।

Ruby एक object_id नामक मेथड प्रदान करता है, जो सभी ऑब्जेक्ट्स के लिए उपलब्ध है। यह पहचानकर्ता एक पूर्णांक लौटाता है और किन्हीं दो ऑब्जेक्ट्स के लिए कभी भी समान नहीं होता। आइए irb में जाकर अपने हाथ गंदे करें; आप अपने टर्मिनल में irb टाइप करके ऐसा कर सकते हैं।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

ऊपर देखा गया है कि स्ट्रिंग्स, इंटीजर्स, एरे, क्लासेस, और यहां तक कि मेथड्स सभी ऑब्जेक्ट्स हैं, क्योंकि उनके पास एक ऑब्जेक्ट ID है।

इस लेख में, हम निम्न अवधारणाओं को विस्तार से कवर करेंगे:

  • क्लासेस और इंस्टेंसेस
  • इनहेरिटेंस
  • पब्लिक, प्राइवेट, और प्रोटेक्टेड मेथड्स
  • मिक्सिन्स
  • मॉड्यूल्स
  • ऑब्जेक्ट हायरार्की

क्लासेस और इंस्टेंसेस

Ruby में, क्लासेस वे हैं जहाँ एक ऑब्जेक्ट के एट्रिब्यूट्स और एटिट्यूड्स (एक्शन) परिभाषित होते हैं। यदि एक ऑब्जेक्ट गोल है (एक एट्रिब्यूट) और बोलने में सक्षम होना चाहिए (एक एक्शन), तो हम उस क्लास से बता सकते हैं जिससे वह संबंधित है क्योंकि ये एट्रिब्यूट्स और एक्शन उस क्लास में मेथड्स नामक किसी चीज़ के रूप में परिभाषित हैं। एक ऑब्जेक्ट जो एक क्लास से संबंधित है, उस क्लास का एक इंस्टेंस कहलाता है और .new का उपयोग करके बनाया (इंस्टेंशिएटेड) जाता है। आइए Human नामक एक क्लास बनाकर शुरू करते हैं। मुझे लगता है कि हम सभी इंसान हैं, तो यह मजेदार होना चाहिए।

class Human
  def initialize(name)
    @name = name
  end
end

इनिशियलाइज़ मेथड एक क्लास के नए इंस्टेंस के निर्माण के लिए आवश्यकताओं की पहचान करता है। ऊपर के मामले में, हम देख सकते हैं कि एक नया इंसान बनाने के लिए, एक नाम आवश्यक है। इसलिए, मानव का एक नया इंस्टेंस Human.new(name) कमांड का उपयोग करके बनाया जा सकता है, जहाँ नाम वह है जो आप चुनते हैं। हमारे मामले में, आइए 'Henry' का उपयोग करें। इसे हमारे irv वातावरण में टेस्ट करने के लिए, हमें केवल फाइल को load './path_to_filename' कमांड का उपयोग करके लोड करना होगा और जब भी परिवर्तन किए जाएं तो फाइल को फिर से निष्पादित करने के लिए कमांड का पुनः उपयोग करना होगा। मेरे मामले में, यह load './Human.rb' है क्योंकि irb उस फ़ोल्डर में खोला गया है जिसमें उक्त फाइल है। irb के बिना कोड चलाने के लिए, हमें हर कमांड से पहले puts स्टेटमेंट जोड़ना होगा ताकि परिणाम दिखाई दें।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

जब हम बिना नाम के एक नया इंसान बनाने का प्रयास करते हैं, तो हमें एक आर्गुमेंट एरर मिलता है क्योंकि नाम आवश्यक है। हालांकि, जब हम इसे सही ढंग से करते हैं, तो हम देखते हैं कि Henry नाम का मानव बनाया गया है और Human क्लास से संबंधित है। इसलिए Henry Human क्लास का एक इंस्टेंस है।

@name वेरिएबल को इंस्टेंस वेरिएबल कहा जाता है क्योंकि यह @ सिंबल से शुरू होता है, जिसका अर्थ है कि इस वेरिएबल को क्लास के भीतर किसी अन्य मेथड द्वारा संदर्भित किया जा सकता है, जब तक कि प्रश्न में क्लास इंस्टेंस मौजूद है। यहाँ, हमने इसे बनाया है और इसे उस नाम के बराबर सेट किया है जिसके साथ ऑब्जेक्ट को इनिशियलाइज़ किया गया था।

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

def name
  @name
end

def no_of_legs
  2
end

def no_of_hands
  2
end

def speak
  'blablabla'
end

हमने बनाए गए मानव का नाम प्राप्त करने, मानव के पैरों और हाथों की संख्या को परिभाषित करने, और मानव को बोलने की क्षमता देने के लिए मेथड्स जोड़े हैं। हम इन मेथड्स को क्लास इंस्टेंस पर instance.method_name का उपयोग करके कॉल कर सकते हैं, जैसा कि नीचे दिखाया गया है।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

क्या होगा यदि हम अपना मन बदलते हैं और तय करते हैं कि हम अपने क्लास इंस्टेंस Henry का नाम बदलना चाहते हैं। Ruby में इसके लिए एक बिल्ट-इन मेथड है, लेकिन इसे मैन्युअली भी किया जा सकता है। मैन्युअली, हम अपने नाम मेथड को केवल एक गेटर मेथड से बदल सकते हैं जो नाम प्राप्त करता है, एक सेटर मेथड में जो इसे एक मान पर सेट करता है यदि कोई प्रदान किया जाता है।

def name=(new_name)
  @name = new_name
end

Ruby के बिल्ट-इन attr_accessor मेथड का उपयोग करके, हम अपने नाम मेथड को छोड़ सकते हैं और इसे लाइन attr_accessor :name से बदल सकते हैं:

class Human
  attr_accessor :name
  def initialize(name)
    @name = name
  end
  # बाकी कोड
end

चुनी गई विधि की परवाह किए बिना, दिन के अंत में, यह वही है जो प्राप्त होता है।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

अब तक बनाए गए सभी मेथड्स को इंस्टेंस मेथड्स कहा जाता है क्योंकि उन्हें क्लास के किसी भी इंस्टेंस पर बुलाया जा सकता है लेकिन क्लास पर नहीं। कुछ ऐसा भी है जिसे क्लास मेथड कहा जाता है, जिसे क्लास पर ही बुलाया जा सकता है न कि उसके इंस्टेंसेस पर। क्लास मेथड्स का नाम मेथड नाम को self. से प्रीफिक्स करके रखा जाता है। यहाँ एक उदाहरण है:

# Human क्लास के भीतर
def self.introduction
  "I am a human, not an alien!"
end

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

जैसा कि हम ऊपर देख सकते हैं, क्लास मेथड केवल क्लास के लिए ही उपलब्ध है न कि उसके इंस्टेंसेस के लिए। इसके अलावा, जैसे इंस्टेंस वेरिएबल्स मौजूद हैं, हमारे पास क्लास वेरिएबल्स भी हैं, जिन्हें दो @ सिंबल से प्रीफिक्स किया जाता है। एक उदाहरण नीचे दिखाया गया है।

class Human
  attr_accessor :name
  @@no_cars_bought = 0 # क्लास वेरिएबल
  def initialize(name)
    @name = name
  end
  def self.no_cars_bought
    @@no_cars_bought
  end
  def buy_car
    @@no_of_cars_bought += 1
    "#{@name} just purchased a car"
  end
end

इस उदाहरण में, हमने हर मानव को कार खरीदने में सक्षम बनाने के लिए एक buy_car मेथड जोड़ा। हमने @@no_of_cars_bought नामक एक क्लास वेरिएबल भी बनाया जो हर बार कार खरीदे जाने पर 1 से बढ़ जाता है। अंत में, हमने no_cars_bought नामक एक क्लास मेथड बनाया जो खरीदी गई कारों की संख्या प्राप्त करता है। आइए देखें कि यह कैसे काम करता है:

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

अब तक परिभाषित सभी मेथड्स को पब्लिक मेथड्स के रूप में जाना जाता है क्योंकि वे क्लास के बाहर से सुलभ हैं। हम प्राइवेट मेथड्स भी परिभाषित कर सकते हैं, जिन्हें केवल क्लास के भीतर एक्सेस किया जा सकता है। आइए एक उदाहरण आजमाते हैं।

# Human क्लास के नीचे
def say_account_number
  "My account number is #{account_number}"
end

private

def account_number
  "1234567890"
end

यह निम्नलिखित देता है:

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

जब हम henry.account_number कॉल करते हैं, तो हमें "NoMethodError" मिलता है क्योंकि account_number एक प्राइवेट मेथड है जिसे केवल क्लास के भीतर से एक्सेस किया जा सकता है। जब इसे say_account_number मेथड के माध्यम से एक्सेस किया जाता है जैसा हमने किया, तो कोई त्रुटि नहीं होती, क्योंकि यह मेथड उसी क्लास में मौजूद है जिसमें प्राइवेट मेथड है। यह ध्यान रखना महत्वपूर्ण है कि private कीवर्ड के बाद हर इंस्टेंस मेथड एक प्राइवेट मेथड बन जाता है; इसलिए, प्राइवेट मेथड्स को क्लास के नीचे सभी पब्लिक मेथड्स के बाद परिभाषित किया जाना चाहिए।

क्या आपने कभी प्रोटेक्टेड मेथड्स के बारे में सुना है? हाँ, सही! ये भी मौजूद हैं, लेकिन हम उनके बारे में इनहेरिटेंस की अवधारणा को समझने के बाद बात करेंगे।

इनहेरिटेंस

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

class Mammal
  def has_hair?
    "Most certainly, Yes"
  end

  def has_complex_brain?
    "Well, as a mammal, what do you expect?"
  end
end

क्या आपको मेरा साइंस क्लास वाक्यांश याद है? यदि हाँ, तो एक ऐसा संबंध बनाना महत्वपूर्ण है जो इस कथन को मान्य करे। तो, हम क्या करते हैं? हम < Mammal को इसकी क्लास परिभाषा में जोड़कर मानव क्लास को Mammal क्लास के गुणों को इनहेरिट करने की अनुमति देते हैं।

class Human < Mammal
  # अन्य सभी कोड
end

एक क्लास जो दूसरी के गुणों को इनहेरिट कर रही है, उसे सबक्लास कहा जाता है, और जिससे यह इनहेरिट करती है उसे सुपरक्लास कहा जाता है। हमारे मामले में, Human सबक्लास है और Mammal सुपरक्लास है। इस बिंदु पर यह ध्यान रखना महत्वपूर्ण है कि यदि आप हमारी तरह सभी क्लासेस को एक फाइल में परिभाषित कर रहे हैं, तो Mammal क्लास परिभाषा आपकी फाइल में Human क्लास से पहले आनी चाहिए, क्योंकि हम किसी वेरिएबल को परिभाषित होने से पहले रेफर नहीं करना चाहते। आइए देखें कि मानव के पास अब कौन सी अतिरिक्त सुविधाएँ हैं।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

ऊपर दिखाए अनुसार, मानव के पास अब Mammal क्लास में परिभाषित सभी एट्रिब्यूट्स तक पहुंच है। यदि हम इनहेरिटेंस को हटा दें (यानी, हम उस कोड लाइन से < Mammal हटा दें) और कमांड henry.class.superclass चलाएँ, तो हमें प्रतिक्रिया के रूप में "Object" मिलता है। यह हमें बताता है कि जब कोई क्लास सीधे किसी अन्य क्लास से इनहेरिट नहीं कर रही होती है तो उसका सुपरक्लास "Object" होता है, जो इस तथ्य को और मजबूत करता है कि Ruby में, क्लासेस भी ऑब्जेक्ट्स हैं।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

अब जब हम जानते हैं कि सुपरक्लास क्या हैं, तो super कीवर्ड के बारे में बात करने का यह सही समय है। Ruby इस कीवर्ड को सुपरक्लास पर पहले से मौजूद मेथड्स के पुन: उपयोग और संशोधन को सक्षम करने के लिए प्रदान करता है। हमारे Mammal सुपरक्लास में, याद रखें कि हमारे पास has_hair? नामक एक मेथड है; क्या होगा यदि हम उस मेथड को जब भी कॉल किया जाए तो मनुष्यों के लिए विशिष्ट कुछ अतिरिक्त जानकारी जोड़ना चाहते हैं? यहीं super कीवर्ड का उपयोग आता है। हमारे Human क्लास में, हम उसी नाम से एक मेथड परिभाषित करते हैं, has_hair?।

def has_hair?
  super + ", but humans can be bald at times"
end

जब super कीवर्ड को कॉल किया जाता है, तो Ruby सुपरक्लास में उस मेथड नाम को खोजता है और उसका परिणाम लौटाता है। उपरोक्त मेथड में, हमने सुपरक्लास के has_hair? मेथड द्वारा उत्पादित परिणाम में कुछ अतिरिक्त जानकारी जोड़ी है।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

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

प्रोटेक्टेड मेथड्स

प्रोटेक्टेड मेथड्स प्राइवेट मेथड्स की तरह काम करते हैं जिसमें वे एक क्लास और उसके सबक्लास के भीतर कॉल करने के लिए उपलब्ध होते हैं। आइए Mammal क्लास के भीतर एक प्रोटेक्टेड मेथड बनाएँ।

 # Mammal क्लास के नीचे
def body_status
  body
end

protected

def body
  "This body is protected"
end

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

ऊपर दिखाए अनुसार, हम body मेथड को एक्सेस नहीं कर सकते क्योंकि यह प्रोटेक्टेड है। हालांकि, हम इसे body_status मेथड से एक्सेस कर सकते हैं, जो Mammal क्लास के अंदर एक और मेथड है। हम उस क्लास के सबक्लास से भी प्रोटेक्टेड मेथड्स एक्सेस कर सकते हैं जहाँ यह परिभाषित है। आइए इसे Human क्लास के भीतर आजमाते हैं।

# Human क्लास के भीतर
def check_body_status
  "Just a human checking that " + body.downcase
end

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

ऊपर दिखाए अनुसार, चाहे body मेथड Human क्लास के भीतर परिभाषित हो और प्रोटेक्टेड हो, Human क्लास इसे एक्सेस कर सकती है क्योंकि यह Mammal क्लास का सबक्लास है। यह सबक्लास एक्सेस प्राइवेट मेथड्स के साथ भी संभव है; हालांकि, इससे यह सवाल उठता है कि इन मेथड्स में क्या अंतर है।

प्रोटेक्टेड मेथड्स को एक्सप्लिसिट रिसीवर्स का उपयोग करके कॉल किया जा सकता है, जैसे receiver.protected_method, जब तक कि प्रश्न में रिसीवर कीवर्ड self है या self के समान क्लास में है। हालांकि, प्राइवेट मेथड्स को केवल एक्सप्लिसिट रिसीवर्स का उपयोग करके तभी कॉल किया जा सकता है जब एक्सप्लिसिट रिसीवर self हो। आइए अपना कोड एडिट करें body.downcase को check_body_status मेथड में self.body.downcase से बदलकर और अपने प्राइवेट मेथड कॉल को भी self शामिल करने के लिए बदलें।

def check_body_status
  "Just a human checking that " + self.body.downcase # body मेथड प्रोटेक्टेड है
end

def say_account_number
  "My account number is #{self.account_number}" # account_number मेथड प्राइवेट है
end

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

नोट: Ruby 2.7 से पहले, कुछ जानकारी प्राप्त करने के लिए प्राइवेट मेथड को कॉल करते समय self का उपयोग करना असंभव था।

आइए आगे बढ़ें और check_body_status मेथड में self शब्द को self के समान क्लास में एक ऑब्जेक्ट से बदलें। हमारे मामले में, self Henry है, जो मेथड्स को कॉल कर रहा है, और Henry Human क्लास का एक इंस्टेंस है, जो Mammal क्लास से इनहेरिट करता है।

def check_body_status
  non_self = Human.new('NotSelf') # self के समान क्लास
  puts "Just #{non_self.name} checking that " + non_self.body.downcase
  # Mammal.new भी self के समान क्लास में है
  "Just a human checking that " + Mammal.new.body.downcase
end

def say_account_number
  non_self = Human.new('NotSelf')
  "My account number is #{non_self.account_number}"
end

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

ऊपर दिखाए अनुसार, प्रोटेक्टेड मेथड्स में self को self के समान क्लास के ऑब्जेक्ट से बदलना संभव है, लेकिन प्राइवेट मेथड्स के साथ यह असंभव है।

मिक्सिन्स

मिक्सिन्स कोड का एक सेट है जिसे एक मॉड्यूल में परिभाषित किया जाता है, जो जब किसी क्लास में शामिल या विस्तारित किया जाता है, तो उस क्लास को अतिरिक्त क्षमताएं प्रदान करता है। कई मॉड्यूल्स को एक क्लास में जोड़ा जा सकता है, क्योंकि इसकी कोई सीमा नहीं है, जो क्लास इनहेरिटेंस में प्राप्त होता है। इस जानकारी के आलोक में, आइए मानव क्लास में मूवमेंट क्षमताओं को जोड़ने के लिए Movement नामक एक मॉड्यूल बनाएँ।

module Movement
  def hop
    "I can hop"
  end

  def swim
    "Ermmmm, I most likely can if I choose"
  end
end

अगला कदम इस मॉड्यूल को हमारे Human क्लास में शामिल करना होगा। यह क्लास में include वाक्यांश जोड़कर किया जाता है। हमारे मामले में, इसमें include Movement को मानव क्लास में जोड़ना शामिल होगा, जैसा कि नीचे दिखाया गया है।

class Human < Mammal
  include Movement
  # बाकी कोड
end

आइए इस कोड को टेस्ट करें:

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

ऊपर दिखाए अनुसार, मॉड्यूल के माध्यम से क्लास में मिक्स किए गए मेथड्स केवल क्लास के इंस्टेंसेस के लिए उपलब्ध हैं न कि क्लास के लिए। क्या होगा यदि हम मॉड्यूल में मेथड्स को क्लास के लिए उपलब्ध कराना चाहते हैं न कि इंस्टेंस के लिए? ऐसा करने के लिए, हम "include" शब्द को "extend" से बदल देते हैं, जैसे extend Movement।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

.extend शब्द का उपयोग क्लास इंस्टेंसेस पर भी किया जा सकता है लेकिन बहुत अलग तरीके से। आइए Parent नामक एक और मॉड्यूल बनाएँ।

module Parent
  def has_kids?
    "most definitely"
  end
end

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

ऊपर दिखाए अनुसार, dad वेरिएबल पर .extend(Parent) का उपयोग करने से has_kids? मेथड उसके लिए उपलब्ध हो जाता है। यह विशेष रूप से उपयोगी है जब हम मॉड्यूल के मेथड्स को हर क्लास इंस्टेंस में मिक्स नहीं करना चाहते। इस प्रकार, extend का उपयोग केवल उस विशेष इंस्टेंस पर किया जा सकता है जिसमें हम रुचि रखते हैं।

मॉड्यूल्स

मॉड्यूल्स क्लासेस, मेथड्स, कॉन्स्टेंट्स, और यहां तक कि अन्य मॉड्यूल्स के लिए हाउसिंग हैं। पहले देखे गए मिक्सिन्स के रूप में उपयोग किए जाने के अलावा, मॉड्यूल्स के अन्य उपयोग हैं। वे आपके कोड को व्यवस्थित करने का एक शानदार तरीका हैं ताकि नामों को टकराने से रोका जा सके, क्योंकि वे नेमस्पेसिंग नामक लाभ प्रदान करते हैं। Ruby में, हर क्लास एक मॉड्यूल है, लेकिन कोई मॉड्यूल क्लास नहीं है, क्योंकि मॉड्यूल्स न तो इंस्टेंशिएट किए जा सकते हैं और न ही इनहेरिट किए जा सकते हैं। नेमस्पेसिंग को समझने के लिए, आइए एक मॉड्यूल बनाएँ जिसमें एक कॉन्स्टेंट, एक क्लास, एक मेथड, और एक और मॉड्यूल हो।

module Male
  AGE = "Above 0"
  class Adult
    def initialize
      puts "I am an adult male"
    end
  end
  def self.hungry
    puts "There's no such thing as male food, I just eat."
  end
  module Grown
    def self.age
      puts "18 and above"
    end
  end
end

आपने देखा होगा कि ऊपर के मॉड्यूल्स में परिभाषित और कॉल किए गए मेथड्स self. से प्रीफिक्स्ड हैं। ऐसा इसलिए है क्योंकि मॉड्यूल्स को इंस्टेंशिएट नहीं किया जा सकता, और उनके भीतर self. प्रीफिक्स के बिना परिभाषित कोई भी मेथड केवल मिक्सिन के रूप में उपलब्ध होगा, जैसा कि हमने पहले मिक्सिन्स पर चर्चा करते समय देखा था। एक मॉड्यूल पर मेथड को कॉल करने के लिए, हमें self.method_name के उपयोग के माध्यम से मेथड नाम पर इसकी पहचान करनी होगी। याद रखें कि हमने क्लास मेथड्स में self कीवर्ड का भी उपयोग किया था; वही सिद्धांत यहाँ लागू होता है।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

ऊपर दिखाए अनुसार, एक मॉड्यूल के भीतर परिभाषित क्लासेस, मॉड्यूल्स, या कॉन्स्टेंट्स तक पहुंचने के लिए, हम module_name::target_name का उपयोग करते हैं। नेमस्पेसिंग अवधारणा को ठीक से समझने के लिए, हम एक और मॉड्यूल बनाएंगे जिसमें Adult नामक एक क्लास हो, और फिर हम देखेंगे कि दोनों क्लासेस कैसे अलग हैं।

module Female
  class Adult
    def initialize
      puts "I am an adult female"
    end
  end
  def self.hungry
    puts "Maybe there's such a thing as female food, I'm not sure. I just need to eat"
  end
end

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

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

ऑब्जेक्ट हायरार्की

क्लासेस, इंस्टेंसेस, मॉड्यूल्स, और इनहेरिटेंस की अवधारणा को समझना अद्भुत है, लेकिन इस क्षेत्र में ज्ञान Ruby में ऑब्जेक्ट हायरार्की को समझे बिना अधूरा है। यह उस क्रम को संदर्भित करता है जिसमें Ruby में एक मेथड की खोज की जाती है। इस हायरार्की को समझने में हमारी मदद करने के लिए कुछ मेथड्स मौजूद हैं; उनमें से एक ancestors मेथड है। यह मेथड क्लास इंस्टेंसेस के लिए उपलब्ध नहीं है लेकिन क्लासेस और उनके पूर्वजों पर बुलाया जा सकता है। एक उदाहरण नीचे दिखाया गया है।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

Human.ancestors के परिणाम से, हम देखते हैं कि यह मेथड प्रश्न में क्लास, उसके सीधे शामिल मॉड्यूल्स, उसके पैरेंट क्लास, और पैरेंट के क्लास के सीधे शामिल मॉड्यूल्स को लौटाता है; यह लूप तब तक जारी रहता है जब तक यह Basic Object तक नहीं पहुंच जाता, जो सभी ऑब्जेक्ट्स की जड़ है।

क्लास के बारे में अधिक जानकारी प्राप्त करने के लिए एक और उपलब्ध मेथड included_modules मेथड है।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

ऊपर दिखाए अनुसार, मानव क्लास में दो मॉड्यूल्स शामिल हैं: वह जिसे हमने include Movement का उपयोग करके सीधे शामिल किया और वह जो Object क्लास में शामिल है। इसका अर्थ है कि प्रत्येक क्लास अपने पूर्वज क्लासेस से क्लास गुणों को इनहेरिट करती है, और उनमें शामिल प्रत्येक मॉड्यूल उसमें शामिल हो जाता है। इस जानकारी के आधार पर, हम Ruby में मेथड लुकअप पथ की पुष्टि करने और इस पथ में दूसरों पर किन क्लासेस की प्राथमिकता है, यह जानने के लिए एक सरल अभ्यास करेंगे। हम समान नाम लेकिन अलग आउटपुट स्ट्रिंग्स वाले मेथड्स को परिभाषित करेंगे और उन्हें Human क्लास, Movement मॉड्यूल, और Mammal क्लास में रखेंगे।

# mammal क्लास में
def find_path
  "Found me in the Mammal class path"
end

# Movement मॉड्यूल में
def find_path
  "Found me in the Movement module path"
end

# Human क्लास में
def find_path
  "Found me in the Human class path"
end

अब आइए इस अभ्यास को करें।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

ऊपर दिखाए अनुसार, जब हम किसी क्लास पर .ancestors कॉल करते हैं तो पूर्वजों को जिस क्रम में रखा जाता है, वही पथ है जिसका पालन उस क्लास के इंस्टेंस पर बुलाए गए मेथड को खोजते समय किया जाता है। हमारे द्वारा बनाए गए Human क्लास इंस्टेंस के लिए, Ruby पहले क्लास में ही मेथड की खोज करता है; यदि नहीं मिला, तो यह किसी भी सीधे शामिल मॉड्यूल्स पर जाता है; यदि नहीं मिला, तो यह सुपरक्लास पर जाता है और चक्र तब तक जारी रहता है जब तक यह BasicObject तक नहीं पहुंच जाता। यदि मेथड वहाँ भी नहीं मिलता है, तो "NoMethodError" लौटाया जाता है। .ancestors मेथड का उपयोग करके, हम किसी ऑब्जेक्ट के लिए लुकअप पथ की पहचान कर सकते हैं और किसी भी समय इसके मेथड्स कहाँ से निकलते हैं।

Ruby एक methods मेथड भी प्रदान करता है, जिसके द्वारा हम किसी भी ऑब्जेक्ट के लिए उपलब्ध सभी मेथड्स की पहचान कर सकते हैं। हम यह दिखाने के लिए घटाव भी कर सकते हैं कि कौन से इसके पैरेंट से आते हैं और कौन से इसके लिए विशिष्ट हैं। एक उदाहरण नीचे दिखाया गया है।

Ruby के ऑब्जेक्ट मॉडल में गहरा गोता: एक व्यापक गाइड

ऊपर दिखाए अनुसार, वेरिएबल Henry के पास बहुत सारे मेथड्स उपलब्ध हैं। हालांकि, जब हम उन्हें Object क्लास के लिए उपलब्ध मेथड्स से घटाते हैं, तो हम पाते हैं कि हम केवल उन लोगों के साथ बचे हैं जिन्हें हमने विशेष रूप से अपनी फाइल में परिभाषित किया था, और हर दूसरा मेथड इनहेरिटेड है। यह हर ऑब्जेक्ट, उसकी क्लास, और उसके किसी भी पूर्वज के लिए समान है। Human.methods, Mammal.methods, Module.methods, और पहले परिभाषित हर दूसरी क्लास या मॉड्यूल से जुड़े कई संयोजनों को आजमाने के लिए बेझिझक अपने हाथ गंदे करें; आप पाएंगे कि यह आपको Ruby ऑब्जेक्ट मॉडल की मजबूत समझ देता है।

  1. रूबी में Dup vs Clone: ऑब्जेक्ट कॉपी करने की तकनीकों में महारत हासिल करें रूबी में Dup vs Clone: ऑब्जेक्ट कॉपी करने की तकनीकों में महारत हासिल करें

    क्या आप जानते हैं कि आप रूबी में ऑब्जेक्ट कॉपी कर सकते हैं? न केवल यह, बल्कि ऐसा करने के लिए दो अलग-अलग मेथड्स हैं! ये मेथड्स हैं: dup clone हम एक पल में अंतर का पता लगाएंगे, लेकिन पहले... आप ऑब्जेक्ट को क्लोन क्यों करना चाहेंगे? रूबी में कई ऑब्जेक्ट्स म्यूटेबल हैं, आप उन्हें बदल सकते हैं। यदि आप

  1. रूबी ऑब्जेक्ट्स को डेकोरेटर पैटर्न से बढ़ाएं: एक व्यावहारिक गाइड रूबी ऑब्जेक्ट्स को डेकोरेटर पैटर्न से बढ़ाएं: एक व्यावहारिक गाइड

    डेकोरेटर डिज़ाइन पैटर्न क्या है? और आप इस पैटर्न का उपयोग अपने रूबी प्रोजेक्ट्स में कैसे कर सकते हैं? डेकोरेटर डिज़ाइन पैटर्न आपको क्लास को बदले बिना नई क्षमताएं जोड़कर एक ऑब्जेक्ट को बढ़ाने में मदद करता है। आइए एक उदाहरण देखें! लॉगिंग और प्रदर्शन इस उदाहरण में हम rest-client जैसे जेम का उपयोग करके

  1. रूबी के फ्रीज मेथड को समझना: ऑब्जेक्ट म्यूटेबिलिटी समझाया गया रूबी के फ्रीज मेथड को समझना: ऑब्जेक्ट म्यूटेबिलिटी समझाया गया

    किसी ऑब्जेक्ट के म्यूटेबल होने का क्या अर्थ है? फैंसी शब्दों को आपको भ्रमित न करने दें, म्यूटेबिलिटी का सीधा सा अर्थ है कि किसी ऑब्जेक्ट की आंतरिक स्थिति को बदला जा सकता है। यह उन ऑब्जेक्ट्स को छोड़कर सभी ऑब्जेक्ट्स का डिफ़ॉल्ट है जिन्हें फ्रीज किया गया है, या जो विशेष ऑब्जेक्ट्स की सूची का हिस्सा ह