Ruby Language
संदेश देना
खोज…
परिचय
ऑब्जेक्ट ओरिएंटेड डिज़ाइन में , ऑब्जेक्ट संदेश प्राप्त करते हैं और उन्हें उत्तर देते हैं। रूबी में, एक संदेश भेजना एक विधि कह रहा है और उस पद्धति का परिणाम उत्तर है।
रूबी संदेश में गतिशील है। जब कोई संदेश यह जानने के बजाय आता है कि इसका उत्तर कैसे दिया जाए तो रूबी एक विधि खोजने के लिए नियमों के पूर्वनिर्धारित सेट का उपयोग करती है जो इसका उत्तर दे सके। हम इन नियमों का उपयोग संदेश को बाधित और जवाब देने के लिए कर सकते हैं, इसे किसी अन्य ऑब्जेक्ट पर भेज सकते हैं या इसे अन्य कार्यों के बीच संशोधित कर सकते हैं।
हर बार किसी वस्तु को एक संदेश प्राप्त होता है रूबी चेक:
- यदि इस ऑब्जेक्ट में एक एकल वर्ग है और यह इस संदेश का उत्तर दे सकता है।
- इस वस्तु की कक्षा को देखता है तो कक्षा की पूर्वजों की श्रृंखला।
- यदि एक विधि इस पूर्वज पर उपलब्ध है और श्रृंखला को आगे बढ़ाती है, तो एक-एक करके जांच करता है।
मैसेज पासिंग इनहेरिटेंस चैन
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