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

रूबी जिस तरह से वस्तुओं को बनाता है उसे बदलना

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

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

कक्षाओं से नई वस्तुएँ बनाने की मूल बातें

आरंभ करने के लिए, आइए देखें कि रूबी में ऑब्जेक्ट कैसे बनाएं। एक नया ऑब्जेक्ट बनाने के लिए (या उदाहरण ), हम new . कहते हैं कक्षा पर। अन्य भाषाओं के विपरीत, new भाषा का एक कीवर्ड नहीं है, बल्कि एक विधि है जिसे किसी अन्य की तरह ही कहा जाता है।

class Dog
end
 
object = Dog.new

नई बनाई गई वस्तु को अनुकूलित करने के लिए, new . के लिए तर्क पारित करना संभव है तरीका। तर्क के रूप में जो कुछ भी पारित किया जाता है, वह प्रारंभकर्ता को पास कर दिया जाएगा।

class Dog
  def initialize(name)
    @name = name
  end
end
 
object = Dog.new('Good boy')

फिर से, अन्य भाषाओं के विपरीत, रूबी में इनिशियलाइज़र भी कुछ विशेष सिंटैक्स या कीवर्ड के बजाय केवल एक विधि है।

इसे ध्यान में रखते हुए, क्या उन तरीकों के साथ गड़बड़ करना संभव नहीं होना चाहिए, जैसे कि यह किसी अन्य रूबी विधि के साथ संभव है? बेशक यह है!

एकल वस्तु के व्यवहार को संशोधित करना

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

module Logging
  def make_noise
    puts "Started making noise"
    super
    puts "Finished making noise"
  end
end
 
class Bird
  def make_noise
    puts "Chirp, chirp!"
  end
end
 
object = Bird.new
object.singleton_class.include(Logging)
object.make_noise
# Started making noise
# Chirp, chirp!
# Finished making noise

इस उदाहरण में, एक Bird ऑब्जेक्ट Bird.new . का उपयोग करके बनाया गया है , और Logging मॉड्यूल को इसके सिंगलटन वर्ग का उपयोग करके परिणामी वस्तु में शामिल किया गया है।

सिंगलटन क्लास क्या है?

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

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

module Logging
  def make_noise
    puts "Started making noise"
    super
    puts "Finished making noise"
  end
end
 
class Bird
  def initialize
    singleton_class.include(Logging)
  end
 
  def make_noise
    puts "Chirp, chirp!"
  end
end
 
object = Bird.new
object.make_noise
# Started making noise
# Chirp, chirp!
# Finished making noise

हालांकि यह अच्छी तरह से काम करता है, अगर हम Bird . का उपवर्ग बनाते हैं , जैसे Duck , इसके प्रारंभकर्ता को super . को कॉल करने की आवश्यकता है Logging को बनाए रखने के लिए व्‍यवहार। जबकि कोई यह तर्क दे सकता है कि super . को ठीक से कॉल करना हमेशा एक अच्छा विचार है जब भी किसी विधि को ओवरराइड किया जाता है, तो आइए एक ऐसा तरीका खोजने का प्रयास करें जिसकी आवश्यकता न हो यह।

अगर हम super . को कॉल नहीं करते हैं उपवर्ग से, हम Logger . का समावेश खो देते हैं कक्षा:

class Duck < Bird
  def initialize(name)
    @name = name
  end
 
  def make_noise
    puts "#{@name}: Quack, quack!"
  end
end
 
object = Duck.new('Felix')
object.make_noise
# Felix: Quack, quack!

इसके बजाय, आइए Bird.new को ओवरराइड करें . जैसा कि पहले बताया गया है, new कक्षाओं पर लागू सिर्फ एक विधि है। इसलिए हम इसे ओवरराइड कर सकते हैं, सुपर को कॉल कर सकते हैं, और नई बनाई गई वस्तु को अपनी आवश्यकताओं के अनुसार संशोधित कर सकते हैं।

class Bird
  def self.new(*arguments, &block)
    instance = super
    instance.singleton_class.include(Logging)
    instance
  end
end
 
object = Duck.new('Felix')
object.make_noise
# Started making noise
# Felix: Quack, quack!
# Finished making noise

लेकिन, क्या होता है जब हम make_noise . कहते हैं प्रारंभकर्ता में? दुर्भाग्य से, क्योंकि सिंगलटन वर्ग में Logging . शामिल नहीं है मॉड्यूल अभी तक, हमें वांछित आउटपुट नहीं मिलेगा।

सौभाग्य से, एक समाधान है:डिफ़ॉल्ट .new . बनाना संभव है allocate . पर कॉल करके शुरुआत से व्यवहार ।

class Bird
  def self.new(*arguments, &block)
    instance = allocate
    instance.singleton_class.include(Logging)
    instance.send(:initialize, *arguments, &block)
    instance
  end
end

कॉलिंग allocate कक्षा की एक नई, प्रारंभिक वस्तु देता है। इसलिए बाद में, हम अतिरिक्त व्यवहार को शामिल कर सकते हैं और उसके बाद ही, initialize . को कॉल कर सकते हैं उस वस्तु पर विधि। (क्योंकि initialize डिफ़ॉल्ट रूप से निजी है, हमें send . का उपयोग करना होगा इसके लिए)।

के बारे में सच्चाई Class#allocate

अन्य विधियों के विपरीत, allocate . को ओवरराइड करना संभव नहीं है . रूबी allocate . के लिए प्रेषण विधियों के पारंपरिक तरीके का उपयोग नहीं करती है आंतरिक रूप से। परिणामस्वरूप, बस ओवरराइड करना allocate बिना ओवरराइड किए new काम नहीं करता। हालांकि, अगर हम allocate को कॉल कर रहे हैं सीधे, रूबी पुनर्निर्धारित विधि को कॉल करेगी। Class#new के बारे में अधिक जानें और Class#allocate रूबी के दस्तावेज़ीकरण में।

हम ऐसा क्यों करेंगे?

बहुत सी चीजों की तरह, रूबी द्वारा कक्षाओं से वस्तुओं को बनाने के तरीके को संशोधित करना खतरनाक हो सकता है और चीजें अप्रत्याशित तरीके से टूट सकती हैं।

फिर भी, वस्तु निर्माण को बदलने के लिए वैध उपयोग के मामले हैं। उदाहरण के लिए, ActiveRecord allocate . का उपयोग करता है एक अलग init_from_db . के साथ सहेजे नहीं गए ऑब्जेक्ट्स के निर्माण के विरोध में डेटाबेस से ऑब्जेक्ट बनाते समय प्रारंभिक प्रक्रिया को बदलने की विधि। यह allocate . का भी उपयोग करता है becomes . के साथ अलग-अलग सिंगल-टेबल इनहेरिटेंस प्रकारों के बीच रिकॉर्ड्स को कन्वर्ट करने के लिए ।

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

रूबी के ऑब्जेक्ट बनाने के डिफ़ॉल्ट तरीके को बदलकर आपके द्वारा कार्यान्वित की गई चीजों के बारे में सुनना हमें अच्छा लगेगा। कृपया अपने विचार @AppSignal पर ट्वीट करने में संकोच न करें।


  1. रूबी में डेकोरेटर डिजाइन पैटर्न

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

  1. रूबी इंटर्नल्स:रूबी ऑब्जेक्ट्स के मेमोरी लेआउट को एक्सप्लोर करना

    क्या आप रूबी इंटर्नल का एक त्वरित दौरा चाहेंगे? फिर आप एक दावत के लिए तैयार हैं। क्योंकि … हम एक साथ यह पता लगाने जा रहे हैं कि रूबी ऑब्जेक्ट को मेमोरी में कैसे रखा जाता है और आप कुछ अच्छी चीजें करने के लिए आंतरिक डेटा संरचनाओं में कैसे हेरफेर कर सकते हैं। अपनी सीट बेल्ट बांधें और रूबी दुभाषिया

  1. रूबी फ्रीज विधि - वस्तु परिवर्तनशीलता को समझना

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