रूबी ब्लॉक, प्रोसेस और लैम्ब्डा।
वे क्या हैं?
वे कैसे काम करते हैं?
वे एक दूसरे से कैसे भिन्न हैं?
आप इस पोस्ट को पढ़कर और भी बहुत कुछ सीखेंगे!
सामग्री
- 1 रूबी ब्लॉक को समझना
- 2 रूबी यील्ड कीवर्ड
- 3 निहित बनाम स्पष्ट ब्लॉक
- 4 कैसे चेक करें कि कोई ब्लॉक दिया गया था या नहीं
- 5 लैम्ब्डा क्या है?
- 6 लैम्ब्डा बनाम प्रोसेस
- 7 क्लोजर
- 8 बाइंडिंग क्लास
- 9 वीडियो ट्यूटोरियल
- 10 रैपिंग अप
- 10.1 संबंधित
रूबी ब्लॉक को समझना
रूबी ब्लॉक छोटे अनाम कार्य हैं जिन्हें विधियों में पारित किया जा सकता है।
ब्लॉक एक do / end
. में संलग्न हैं कथन या कोष्ठक के बीच {}
, और उनके कई तर्क हो सकते हैं।
तर्क नाम दो पाइपों के बीच परिभाषित किए गए हैं |
वर्ण।
यदि आपने each
का उपयोग किया है पहले, तब आपने ब्लॉक का उपयोग किया है!
यहां एक उदाहरण दिया गया है :
# फॉर्म 1:सिंगल लाइन ब्लॉकों के लिए अनुशंसित[1, 2, 3]। प्रत्येक { |num| संख्या डालता है } ^^^^^ ^^^^^^^ ब्लॉक तर्क बॉडी को ब्लॉक करें
# फॉर्म 2:बहु-पंक्ति ब्लॉकों के लिए अनुशंसित[1, 2, 3]। प्रत्येक करते हैं |num| अंक डालता है
रूबी ब्लॉक उपयोगी है क्योंकि यह आपको थोड़ा तर्क (कोड) सहेजने और बाद में इसका उपयोग करने की अनुमति देता है।
यह कुछ ऐसा हो सकता है जैसे किसी फ़ाइल में डेटा लिखना, तुलना करना कि क्या एक तत्व दूसरे के बराबर है, या एक त्रुटि संदेश भी प्रिंट कर रहा है।
रूबी यील्ड कीवर्ड
yield
क्या करता है रूबी में मतलब है?
यील्ड एक रूबी कीवर्ड है जब आप इसका उपयोग करते हैं तो यह एक ब्लॉक को कॉल करता है।
USE इस तरह से ब्लॉक करता है!
जब आप yield
. का उपयोग करते हैं कीवर्ड, ब्लॉक के अंदर का कोड चलेगा &अपना काम करें।
ठीक उसी तरह जब आप एक नियमित रूबी विधि कहते हैं।
यहां एक उदाहरण दिया गया है :
def print_once yieldendprint_once { डालता है "ब्लॉक चलाया जा रहा है" }
यह print_once
. को दिए गए किसी भी ब्लॉक को चलाता है , परिणामस्वरूप, "Block is being run"
स्क्रीन पर प्रिंट हो जाएगा।
क्या आप जानते हैं...
वह yield
कई बार इस्तेमाल किया जा सकता है?
हर बार जब आप yield
. कहते हैं , ब्लॉक चलेगा, तो यह उसी विधि को फिर से कॉल करने जैसा है।
उदाहरण :
डिफ प्रिंट_ट्वाइस यील्ड यील्डएंडप्रिंट_ट्विस {पुट्स "हैलो" }# "हैलो"# "हैलो"
और बिल्कुल तरीकों की तरह…
आप yield
. के लिए जितने भी तर्क दे सकते हैं ।
उदाहरण :
def one_two_three उपज 1 उपज 2 उपज 3endone_two_three { |number| नंबर डालता है * 10 }# 10, 20, 30
ये तर्क तब खंड के तर्क बन जाते हैं।
इस उदाहरण में number
।
अंतर्निहित बनाम स्पष्ट ब्लॉक
ब्लॉक "स्पष्ट" या "अंतर्निहित" हो सकते हैं।
स्पष्ट का अर्थ है कि आप इसे अपनी पैरामीटर सूची में एक नाम देते हैं।
आप एक स्पष्ट ब्लॉक को किसी अन्य विधि में पास कर सकते हैं या बाद में उपयोग करने के लिए इसे एक चर में सहेज सकते हैं।
यहां एक उदाहरण दिया गया है :
def clear_block(&block) block.call # जैसा कि yieldendexplicit_block {पुट "एक्सप्लिसिट ब्लॉक कॉल" }
&block
पर ध्यान दें पैरामीटर…
इस तरह आप ब्लॉक के नाम को परिभाषित करते हैं!
कैसे जांचें कि कोई ब्लॉक दिया गया था या नहीं
यदि आप yield
. की कोशिश करते हैं बिना ब्लॉक के आपको no block given (yield)
मिलेगा त्रुटि।
आप जांच सकते हैं कि block_given?
. के साथ कोई ब्लॉक पास किया गया है या नहीं विधि।
उदाहरण :
def do_something_with_block रिटर्न "कोई ब्लॉक नहीं दिया गया" जब तक कि ब्लॉक_गिवेन न हो? उपज
यह त्रुटि को रोकता है यदि कोई आपके तरीके को बिना किसी अवरोध के कॉल करता है।
एक लैम्ब्डा क्या है?
लैम्ब्डा एक ब्लॉक और उसके मापदंडों को कुछ विशेष सिंटैक्स के साथ परिभाषित करने का एक तरीका है।
आप इस लैम्ब्डा को बाद में उपयोग के लिए एक चर में सहेज सकते हैं।
रूबी लैम्ब्डा को परिभाषित करने के लिए वाक्यविन्यास ऐसा दिखता है:
say_something =-> { "यह एक लैम्ब्डा है" डालता है }<ब्लॉकक्वॉट>
आप वैकल्पिक सिंटैक्स का भी उपयोग कर सकते हैं:lambda
के बजाय ->
।
लैम्ब्डा को परिभाषित करने से उसके अंदर कोड नहीं चलेगा, जैसे किसी विधि को परिभाषित करने से विधि नहीं चलेगी, आपको call
का उपयोग करने की आवश्यकता है उसके लिए विधि।
उदाहरण :
say_something =-> { "यह एक लैम्ब्डा है" डालता है }say_something.call# "यह एक लैम्ब्डा है"
call
. करने के और भी तरीके हैं एक lambda
, यह जानना अच्छा है कि वे मौजूद हैं, हालांकि, मैं call
. के साथ चिपके रहने की सलाह देता हूं स्पष्टता के लिए।
यहां सूची है :
my_lambda =-> { पुट "लैम्ब्डा कॉल" }my_lambda.callmy_lambda.()my_lambda[]my_lambda.===
लैम्ब्डा तर्क भी ले सकते हैं, यहाँ एक उदाहरण है:
times_two =->(x) { x * 2 }times_two.call(10)# 20
यदि आप तर्कों की गलत संख्या को lambda
. पर पास करते हैं , यह एक नियमित विधि की तरह एक अपवाद उठाएगा।
लैम्बडास बनाम प्रोसेस
प्रोसेस एक बहुत ही समान अवधारणा है…
अंतरों में से एक यह है कि आप उन्हें कैसे बनाते हैं।
उदाहरण :
my_proc =Proc.new { |x| x डालता है }
कोई समर्पित lambda
नहीं है कक्षा। एक lambda
बस एक विशेष Proc
है वस्तु। यदि आप Proc
. से इंस्टेंस विधियों पर एक नज़र डालते हैं , आप देखेंगे कि एक lambda?
विधि।
अब :
एक खरीद लैम्ब्डा से अलग व्यवहार करती है, खासकर जब तर्कों की बात आती है:
t =Proc.new {|x,y| डालता है "मुझे तर्कों की परवाह नहीं है!" }t.call# "मुझे तर्कों की परवाह नहीं है!"
procs
. के बीच एक और अंतर &lambdas
return
. पर वे कैसे प्रतिक्रिया करते हैं बयान।
एक lambda
return
सामान्य रूप से, एक नियमित विधि की तरह।
लेकिन एक proc
return
करने का प्रयास करेंगे वर्तमान संदर्भ से।
यहां मेरा मतलब है :
यदि आप निम्न कोड चलाते हैं, तो आप देखेंगे कि proc
. कैसे एक LocalJumpError
उठाता है अपवाद।
इसका कारण यह है कि आप return
नहीं कर सकते हैं शीर्ष-स्तरीय संदर्भ से।
इसे आजमाएं :
# काम करना चाहिएmy_lambda =-> {वापसी 1} "लैम्ब्डा परिणाम:#{my_lambda.call}" डालता है /पूर्व>अगर
proc
एक विधि के अंदर था, फिरreturn
को कॉल कर रहा था उस विधि से लौटने के बराबर होगा।यह निम्नलिखित उदाहरण में प्रदर्शित किया गया है।
def call_proc, "पहले proc" डालता है my_proc =Proc.new {रिटर्न 2 } my_proc.call "आफ्टर proc" endp call_proc# प्रिंट करता है "बिफोर प्रोक" लेकिन "आफ्टर प्रोक" नहींयहां इस बात का सारांश दिया गया है कि कैसे
procs
औरlambdas
अलग हैं:
- लैम्बडास को
-> {}
with से परिभाषित किया गया है और प्रोसेसProc.new {}
. के साथ । - प्रक्रिया वर्तमान पद्धति से लौटती है, जबकि लैम्ब्डा लैम्ब्डा से ही वापस आती है।
- प्रक्रिया तर्कों की सही संख्या की परवाह नहीं करती है, जबकि लैम्ब्डा एक अपवाद उठाएगा।
इस सूची पर एक नज़र डालने पर, हम देख सकते हैं कि lambdas
procs
. की तुलना में एक नियमित विधि के बहुत करीब हैं हैं।
क्लोजर
रूबी प्रोसेस और लैम्ब्डा में एक और विशेष विशेषता है। जब आप रूबी प्रो बनाते हैं, तो यह इसके साथ वर्तमान निष्पादन क्षेत्र को कैप्चर करता है।
यह अवधारणा, जिसे कभी-कभी क्लोजर भी कहा जाता है, का अर्थ है कि एक proc
स्थानीय चर और विधियों जैसे मूल्यों को उस संदर्भ से ले जाएगा जहां इसे परिभाषित किया गया था।
वे वास्तविक मान नहीं रखते हैं, लेकिन उनके लिए एक संदर्भ है, इसलिए यदि खरीद के बाद चर बदलते हैं, तो खरीद में हमेशा नवीनतम संस्करण होगा।
आइए एक उदाहरण देखें :
def call_proc(my_proc) count =500 my_proc.callendcount =1my_proc =Proc.new {puts count}p call_proc(my_proc) # यह प्रिंट क्या करता है?
इस उदाहरण में हमारे पास एक स्थानीय count
है वेरिएबल, जो 1
. पर सेट है ।
हमारे पास my_proc
. नाम की एक खरीद भी है , और एक call_proc
विधि जो चलती है (call
. के माध्यम से) विधि) कोई भी खरीद या लैम्ब्डा जिसे तर्क के रूप में पारित किया जाता है।
आपको क्या लगता है कि यह प्रोग्राम क्या प्रिंट करेगा?
ऐसा लगता है कि 500
सबसे तार्किक निष्कर्ष है, लेकिन 'क्लोजर' प्रभाव के कारण यह 1
print प्रिंट करेगा ।
ऐसा इसलिए होता है क्योंकि खरीद count
. के मान का उपयोग कर रही है उस जगह से जहां खरीद को परिभाषित किया गया था, और वह विधि परिभाषा से बाहर है।
द बाइंडिंग क्लास
रूबी प्रोसेस और लैम्ब्डा इस दायरे की जानकारी कहाँ संग्रहीत करते हैं?
मैं आपको Binding
. के बारे में बताता हूं कक्षा…
जब आप एक Binding
बनाते हैं Binding
. के माध्यम से वस्तु विधि, आप कोड में इस बिंदु पर एक 'एंकर' बना रहे हैं।
इस बिंदु पर परिभाषित प्रत्येक चर, विधि और वर्ग बाद में इस ऑब्जेक्ट के माध्यम से उपलब्ध होंगे, भले ही आप पूरी तरह से अलग दायरे में हों।
उदाहरण :
def रिटर्न_बाइंडिंग फू =100 बाइंडिंगएंड# फू उपलब्ध है, बाइंडिंग के लिए धन्यवाद, # भले ही हम उस विधि से बाहर हैं# जहां इसे परिभाषित किया गया था। सीधे फू प्रिंट करें आपको एक त्रुटि मिलेगी। # इसका कारण यह है कि फू को कभी भी विधि के बाहर परिभाषित नहीं किया गया था। फू डालता है
दूसरे शब्दों में, Binding
. के संदर्भ में कुछ निष्पादित करना ऑब्जेक्ट वैसा ही है जैसे कि वह कोड उसी स्थान पर था जहां वह Binding
. था परिभाषित किया गया था ('एंकर' रूपक याद रखें)।
आपको Binding
. का उपयोग करने की आवश्यकता नहीं है ऑब्जेक्ट सीधे, लेकिन यह जानना अभी भी अच्छा है कि यह एक चीज़ है 🙂
वीडियो ट्यूटोरियल
रैपिंग अप
इस पोस्ट में आपने सीखा कि ब्लॉक कैसे काम करते हैं, रूबी प्रोसेस और लैम्ब्डा के बीच अंतर और जब भी आप ब्लॉक बनाते हैं तो "क्लोजर" प्रभाव के बारे में भी सीखा।
एक चीज जो मैंने कवर नहीं की वह है करी विधि।
यह विधि आपको कुछ या सभी आवश्यक तर्कों को पारित करने की अनुमति देती है।
यदि आप केवल आंशिक संख्या में तर्कों में पास होते हैं, तो आपको इन तर्कों के साथ पहले से ही 'प्री-लोडेड' के साथ एक नई खरीद मिलेगी, जब सभी तर्कों की आपूर्ति की जाती है तो खरीद को निष्पादित किया जाएगा।
मुझे आशा है कि आपको यह पोस्ट अच्छा लगा होगा!
नीचे दिए गए फॉर्म में सदस्यता लेना न भूलें और इसे अपने दोस्तों के साथ साझा करें