रूबी क्लोजर: ब्लॉक, प्रक्रियाएं, और लम्बदा - अंतर क्या है?

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

खंड

ब्लॉक को do..end या {..} के माध्यम से पहचाना जा सकता है और नीचे दिखाए अनुसार तर्क दिए जा सकते हैं:

रूबी में प्रत्येक विधि एक अवैध ब्लॉक को एक अवैध पैरामीटर के रूप में ले सकती है, निम्न उदाहरण में:

ऊपर दिए गए उदाहरण में इसका क्या मतलब है, हम ब्लॉकिंग की ग्रीटिंग विधि पर स्विच कर रहे हैं, और हमें ब्लॉक शुरू करने के लिए फसल कीवर्ड का उपयोग करने की आवश्यकता है। हम पैरामीटर नाम पर पारित एक तर्क के रूप में ब्लॉक को उत्पन्न करने के लिए एक स्थानीय चर ("एशले" स्ट्रिंग का उल्लेख करते हैं जो एक तर्क के रूप में ग्रीटिंग विधि को पारित करते हैं)। ब्लॉक के अंदर, "हैलो # {नाम}!" टिप्पणी कहते हैं। अब देखते हैं कि अगर हम ब्लॉक पर आपत्ति नहीं करते हैं तो क्या होगा।

ऊपर दिए गए उदाहरण में, हम यह तर्क नहीं दे रहे हैं कि कोई भी तर्क उस खंड को पारित नहीं किया जाता है जो एकल पैरामीटर को स्वीकार करता है। अजीब बात है, ArgumentError वापस नहीं किया गया है। ऐसा इसलिए है क्योंकि ब्लॉक तर्क की संख्या में वृद्धि नहीं करते हैं। इसके बजाय, जब कोई ब्लॉक पैरामीटर को स्वीकार करता है, अगर हम किसी ब्लॉक को तर्क नहीं देते हैं, तो पैरामीटर शून्य पर लौटता है। चूंकि ब्लॉक पैरामीटर नाम के लिए कोई तर्क पारित नहीं किया जाता है, इसलिए स्थानीय चर का नाम शून्य है, इसलिए ग्रीटिंग विधि नमस्ते है! एक अतिरिक्त जगह है जहाँ अभिवादन के बाद नाम होना चाहिए।

procs

नीचे दिखाए अनुसार कैश रजिस्टर बनाने के दो तरीके हैं:

पहले उदाहरण में, हम प्रोक क्लास में एक नई विधि को कॉल करके एक प्रोक ऑब्जेक्ट बनाते हैं और इसे एक तर्क के रूप में ब्लॉक पर पास करते हैं। दूसरे उदाहरण में, हम कर्नेल मॉड्यूल को एक विधि के रूप में कॉल विधि द्वारा पास कर सकते हैं।

ब्लॉक को सक्रिय करने के लिए आपको proc ऑब्जेक्ट को कॉल करना होगा।

ऊपर दिए गए उदाहरण में, हम proc1 में कॉल विधि को कॉल ऑब्जेक्ट को इंगित करते हैं। यह तब एक तर्क के रूप में कॉल विधि को पारित किया जाता है। छपे हैं।

निम्नलिखित उदाहरण दिखाता है कि अगर हम रैली में नहीं जाते हैं तो क्या होगा।

जब Proc ऑब्जेक्ट proc1 में कॉल विधि कहा जाता है, हम बहस नहीं करते हैं। इसका मतलब है कि ब्लॉक पैरामीटर नाम के लिए कोई तर्क पारित नहीं किया गया है। तर्क नहीं उठाया गया था क्योंकि परियोजनाओं ने ब्लॉक के रूप में एक ही तरह के नियम साझा किए थे और तर्कों की संख्या को ध्यान में नहीं रखा था। ब्लॉक की तरह, यदि कोई पैरामीटर निर्दिष्ट नहीं है, तो शून्य को शून्य पर असाइन किया गया है। नमस्कार! हमारे। यही कारण है कि हमें इसका परिणाम मिलता है।

Lambdalar

लंबोदा बनाने के दो तरीके यहां दिए गए हैं।

पहले उदाहरण में, हम लैंबडा बनाने के लिए कर्नेल मॉड्यूल से लैंबडा विधि कहते हैं और एक तर्क के रूप में एक ब्लॉक के रूप में पास करते हैं। दूसरे उदाहरण में, हम रूबी के सिंटैक्टिक शुगर का उपयोग करके एक लैम्ब्डा बना रहे हैं। उदाहरण में हम उपयोग करते हैं -> और फिर हम ब्लॉक पैरामीटर को कोष्ठक में रखते हैं और फिर ब्लॉक में जाते हैं। तो लैंबडा बनाने के दो अलग-अलग तरीकों के बीच मुख्य अंतर यह है कि पहले उदाहरण में, ब्लॉक पैरामीटर ब्लॉक के अंदर हैं, और दूसरे उदाहरण में, ब्लॉक पैरामीटर -> के बजाय कोष्ठक में हैं।

ध्यान देने वाली एक बात यह है कि हम ऐसा करने के लिए एक लंबोदर नहीं बना सकते हैं:

ऐसा इसलिए है क्योंकि लैम्ब्डा वास्तव में लैम्ब्डा ऑब्जेक्ट नहीं हैं, वे प्रोक ऑब्जेक्ट हैं। प्रिज्म और लैम्ब्डा के बीच मुख्य अंतर यह है कि उनके पास अतालता के विभिन्न नियम हैं।

चूंकि लैम्ब्डा प्रोक की वस्तु है, इसलिए हम लैम्बडा में कॉलबैक पद्धति को कॉल कर सकते हैं और ब्लॉक निष्पादित किया जाता है। ऊपर दिए गए पहले उदाहरण में, हम कॉलबैक विधि को lambda1 में कॉल करते हैं और ब्लॉक पैरामीटर नाम पर जाते हैं और कहते हैं "हैलो" {{}}! आइए एशले तर्क प्राप्त करें। नमस्ते एशले! दूसरे उदाहरण में, lambda1 को तर्क के बिना कॉल किया जाता है और ArgumentError को लौटा दिया जाता है क्योंकि ब्लॉक एक पैरामीटर प्राप्त करता है। इससे पता चलता है कि, प्रक्रियाओं और ब्लॉकों के विपरीत, लैम्ब्डा तर्क गिनती बनाते हैं।

एक आखिरी बात ...

एक और चीज जो ब्लॉक, सिलेंडर, और लैम्ब्स को सेट करती है, वह है रिटर्न कुंजी कैसे काम करती है।

खंड

जब मैं निम्नलिखित कोड का उपयोग करता हूं:

मुझे यह त्रुटि संदेश प्राप्त हुआ:

अप्रत्याशित वापसी (लोकलजंपायर)

इस प्रकार, जब विधि ब्लॉक हो रही है तो क्या हो रहा है, कार्यक्रम का निष्पादन विधि के कार्यान्वयन से ब्लॉक तक जाता है। जब हम एक विधि लागू करते हैं, तो आमतौर पर प्रोग्राम LocalJumpError को वापस कर देते हैं, लेकिन हमें कभी भी ब्लॉक नहीं मिलता है। यह कार्यक्रम के कार्यान्वयन के लिए विधि के कार्यान्वयन से एक ब्लॉक तक मौजूद है जो मौजूद नहीं है, इसलिए एक त्रुटि होती है। LocalJumpError त्रुटि को पारित करने के लिए कोई बाधा नहीं थी!

यही कारण है कि हम ऊपर दिए उदाहरण में LocalJumpError प्राप्त करते हैं। विधि के ब्लॉक में जाने के बाद, प्रोग्राम उस ब्लॉक पर कूद गया जिसमें रिटर्न कीवर्ड था। LocalJumpError को वापस कर दिया गया था, इसलिए इसने विधि को वापस किए बिना कार्यक्रम का निष्पादन रोक दिया।

procs

जब मैं निम्नलिखित कोड का उपयोग करता हूं:

मैं ब्लॉक मिसाल के रूप में वही गलतियाँ नहीं करता। एक बार जब प्रो को बुलाया जाता है और ब्लॉक में "हैलो" शब्द का मूल्यांकन किया जाता है, तो प्रोग्राम चलना बंद हो जाता है और proc_example विधि से "हैलो" वापस आ जाता है। ध्यान दें कि "अच्छा" विधि की अंतिम पंक्ति का मूल्यांकन कभी नहीं किया गया है। ऐसा इसलिए है क्योंकि प्रक्रिया ब्लॉक से ही लौटती है और विधि को निष्पादित करने से रोकती है।

Lambdalar

जब मैं निम्नलिखित कोड का उपयोग करता हूं:

कार्यक्रम का कार्यान्वयन अनुसूची के आगे नहीं रुका। जब लैम्ब्डा 1 को कॉल किया जाता है और ब्लॉक को कॉल किया जाता है, तो प्रोग्राम का निष्पादन ब्लॉक से वापस नहीं आता है, जैसा कि प्रॉक्सी उदाहरण में है। इसके बजाय, कार्यक्रम जारी है और "अलविदा" को lambda_example विधि द्वारा लौटाया गया है। इस प्रकार, जब ब्लॉक में रिटर्न कीवर्ड का मूल्यांकन किया जाता है, तो लैम्ब्डा रिटर्न कीवर्ड को अनदेखा करता है और प्रोग्राम जारी रहता है।

रूबी पर बंद करना मुश्किल हो सकता है और यदि आप मेरे ब्लॉग बंद होने पर कुछ भी याद करते हैं तो आप उन्हें साझा करने के लिए स्वतंत्र हो सकते हैं!