खोज…


परिचय

ऑब्जेक्ट ओरिएंटेड डिज़ाइन में , ऑब्जेक्ट संदेश प्राप्त करते हैं और उन्हें उत्तर देते हैं। रूबी में, एक संदेश भेजना एक विधि कह रहा है और उस पद्धति का परिणाम उत्तर है।

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

हर बार किसी वस्तु को एक संदेश प्राप्त होता है रूबी चेक:

  1. यदि इस ऑब्जेक्ट में एक एकल वर्ग है और यह इस संदेश का उत्तर दे सकता है।
  2. इस वस्तु की कक्षा को देखता है तो कक्षा की पूर्वजों की श्रृंखला।
  3. यदि एक विधि इस पूर्वज पर उपलब्ध है और श्रृंखला को आगे बढ़ाती है, तो एक-एक करके जांच करता है।

मैसेज पासिंग इनहेरिटेंस चैन

class Example
  def example_method
    :example
  end

  def subexample_method
    :example
  end

  def not_missed_method
    :example
  end

  def method_missing name
    return :example if name == :missing_example_method
    return :example if name == :missing_subexample_method
    return :subexample if name == :not_missed_method
    super
  end
end

class SubExample < Example
  def subexample_method
    :subexample
  end

  def method_missing name
    return :subexample if name == :missing_subexample_method
    return :subexample if name == :not_missed_method
    super
  end
end

s = Subexample.new

SubExample#subexample_method लिए एक उपयुक्त विधि खोजने के लिए Ruby पहले SubExample#subexample_method पूर्वजों की श्रृंखला को SubExample

SubExample.ancestors # => [SubExample, Example, Object, Kernel, BasicObject]

यह SubExample से शुरू होता है। यदि हम subexample_method संदेश भेजते हैं, subexample_method रूबी एक उपलब्ध एक को चुनता है SubExample और Example#subexample_method अनदेखा करता है।

s.subexample_method # => :subexample

SubExample बाद यह Example जाँचता है। अगर हम example_method रूबी को भेजते हैं example_method तो अगर SubExample इसका उत्तर दे सकता है या नहीं और चूंकि यह रूबी श्रृंखला में नहीं जा सकता है और Example में दिखता है।

s.example_method # => :example

रूबी के बाद सभी परिभाषित तरीकों की जाँच करता है तो यह देखने के लिए method_missing चलाता है कि क्या यह उत्तर दे सकता है या नहीं। अगर हम भेज missing_subexample_method रूबी पर एक परिभाषित विधि को खोजने के लिए सक्षम नहीं होगा SubExample तो यह करने के लिए ऊपर ले जाता है Example । यह Example या श्रृंखला में उच्चतर किसी भी अन्य वर्ग पर एक परिभाषित विधि नहीं पा सकता है। रूबी शुरू होता है और method_missing चलाता है। method_missing की SubExample का उत्तर दे सकते missing_subexample_method

s.missing_subexample_method # => :subexample

हालांकि अगर एक विधि परिभाषित की गई है तो रूबी श्रृंखला में अधिक होने पर भी परिभाषित संस्करण का उपयोग करती है। उदाहरण के लिए अगर हम भेज not_missed_method भले ही method_missing की SubExample यह का उत्तर दे सकते रूबी पर चलता है SubExample क्योंकि यह है कि नाम और में दिखता है के साथ एक परिभाषित विधि नहीं है Example जो एक है।

s.not_missed_method # => :example

मॉड्यूल संरचना के माध्यम से संदेश गुजर रहा है

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

class Example
end

module Prepended
  def initialize *args
    return super :default if args.empty?
    super
  end
end

module FirstIncluded
  def foo
    :first
  end
end

module SecondIncluded
  def foo
    :second
  end
end

class SubExample < Example
  prepend Prepended
  include FirstIncluded
  include SecondIncluded

  def initialize data = :subexample
    puts data
  end
end

SubExample.ancestors # => [Prepended, SubExample, SecondIncluded, FirstIncluded, Example, Object, Kernel, BasicObject]

s = SubExample.new # => :default
s.foo # => :second

संदेश बाधित करना

संदेशों को बाधित करने के दो तरीके हैं।

  • किसी भी गैर परिभाषित संदेश को बाधित करने के लिए method_missing का उपयोग करें।
  • संदेश को इंटरसेप्ट करने के लिए चेन के बीच में एक विधि को परिभाषित करें

संदेशों को बाधित करने के बाद, यह संभव है:

  • उन्हें उत्तर दें।
  • उन्हें कहीं और भेज दो।
  • संदेश या उसका परिणाम संशोधित करें।

method_missing और संदेश का जवाब देने में बाधा method_missing :

class Example
  def foo
    @foo
  end

  def method_missing name, data
    return super unless name.to_s =~ /=$/
    name = name.to_s.sub(/=$/, "")
    instance_variable_set "@#{name}", data
  end
end

e = Example.new

e.foo = :foo
e.foo # => :foo

संदेश को इंटरसेप्ट करना और उसे संशोधित करना:

class Example
  def initialize title, body
  end
end

class SubExample < Example
end

अब कल्पना करते हैं कि हमारा डेटा "शीर्षक: शरीर" है और हमें Example कॉल करने से पहले उन्हें विभाजित करना होगा। हम SubExample पर initialize को परिभाषित कर सकते हैं।

class SubExample < Example
  def initialize raw_data
    processed_data = raw_data.split ":"

    super processed_data[0], processed_data[1]
  end
end

संदेश को इंटरसेप्ट करना और दूसरी वस्तु पर भेजना:

class ObscureLogicProcessor
  def process data
    :ok
  end
end

class NormalLogicProcessor
  def process data
    :not_ok
  end
end

class WrapperProcessor < NormalLogicProcessor
  def process data
    return ObscureLogicProcessor.new.process data if data.obscure?

    super
  end
end


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow