हां, यह पहली बार में थोड़ा हैरान करने वाला है।
रूबी में, कोड के मनमाने खंडों को करने के लिए तरीकों को एक कोड ब्लॉक प्राप्त हो सकता है।
जब कोई विधि किसी ब्लॉक की अपेक्षा करती है, तो यह yield
फ़ंक्शन को कॉल करके इसे आमंत्रित करता है।
उदाहरण के लिए, किसी सूची पर पुनरावृति करना या कोई कस्टम एल्गोरिथ्म प्रदान करना बहुत आसान है।
निम्नलिखित उदाहरण लें:
मैं Person
एक नाम के साथ आरम्भ की गई कक्षा को परिभाषित करने जा रहा हूँ , और एक do_with_name
विधि प्रदान करता हूँ , जब आह्वान किया जाता है, बस name
प्राप्त विशेषता को, ब्लॉक को प्राप्त होगा।
class Person
def initialize( name )
@name = name
end
def do_with_name
yield( @name )
end
end
इससे हम उस पद्धति को कॉल कर सकते हैं और एक मनमाना कोड ब्लॉक कर सकते हैं।
उदाहरण के लिए, नाम छापने के लिए हम क्या करेंगे:
person = Person.new("Oscar")
#invoking the method passing a block
person.do_with_name do |name|
puts "Hey, his name is #{name}"
end
प्रिंट होगा:
Hey, his name is Oscar
ध्यान दें, ब्लॉक एक पैरामीटर के रूप में प्राप्त होता है, जिसे एक चर कहा जाता है name
(एनबी आप इस चर को अपनी पसंद के अनुसार कुछ भी कह सकते हैं, लेकिन यह इसे कॉल करने के लिए समझ में आता है name
)। जब कोड इनवॉइस करता है yield
तो इस मान को भरता है @name
।
yield( @name )
हम एक अलग कार्रवाई करने के लिए एक और ब्लॉक प्रदान कर सकते हैं। उदाहरण के लिए, नाम को उल्टा करें:
#variable to hold the name reversed
reversed_name = ""
#invoke the method passing a different block
person.do_with_name do |name|
reversed_name = name.reverse
end
puts reversed_name
=> "racsO"
हमने बिल्कुल उसी विधि का उपयोग किया ( do_with_name
) - यह सिर्फ एक अलग ब्लॉक है।
यह उदाहरण तुच्छ है। अधिक दिलचस्प उपयोग एक सरणी में सभी तत्वों को फ़िल्टर करने के लिए हैं:
days = ["monday", "tuesday", "wednesday", "thursday", "friday"]
# select those which start with 't'
days.select do | item |
item.match /^t/
end
=> ["tuesday", "thursday"]
या, हम एक कस्टम प्रकार एल्गोरिथ्म भी प्रदान कर सकते हैं, उदाहरण के लिए स्ट्रिंग आकार के आधार पर:
days.sort do |x,y|
x.size <=> y.size
end
=> ["monday", "friday", "tuesday", "thursday", "wednesday"]
मुझे उम्मीद है कि यह आपको इसे बेहतर ढंग से समझने में मदद करेगा।
BTW, यदि ब्लॉक वैकल्पिक है तो आपको इसे कॉल करना चाहिए:
yield(value) if block_given?
यदि वैकल्पिक नहीं है, तो इसे लागू करें।
संपादित करें
@hmak ने इन उदाहरणों के लिए एक repl.it बनाया: https://repl.it/@makstaks/blocksandyieldsrubbxample