Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

रेल्स के छिपे रत्नों को उजागर करें: ActiveSupport के StringInquirer में महारत हासिल करें

रेल्स एक बड़ा फ्रेमवर्क है, और यह हर साल बड़ा होता जा रहा है। इससे कुछ उपयोगी फीचर्स का किसी का ध्यान न जाना आसान हो जाता है। इस श्रृंखला में, हम रेल्स में विशिष्ट कार्यों के लिए अंतर्निहित कुछ कम-ज्ञात कार्यक्षमता पर एक नज़र डालेंगे।

इस श्रृंखला के पहले लेख में, हम यह देखने जा रहे हैं कि Rails.env.test? को कॉल करना वास्तव में ActiveSupport से कम-ज्ञात StringInquirer क्लास का उपयोग करके हुड के तहत कैसे काम करता है। एक कदम आगे जाकर, हम StringInquirer सोर्स कोड के माध्यम से भी चलेंगे कि यह कैसे काम करता है, जो (स्पॉइलर अलर्ट) रूबी के मेटाप्रोग्रामिंग का एक सरल उदाहरण है विशेष method_missing मेथड के माध्यम से।

Rails.env हेल्पर

आपने शायद पहले से ही कोड देखा है जो रेल्स एनवायरनमेंट की जांच करता है:

if Rails.env.test? # हार्ड-कोडेड मान वापस करें... else # एक्सटर्नल API से संपर्क करें... end 

हालांकि, test? वास्तव में क्या करता है, और यह मेथड कहां से आता है?

यदि हम कंसोल में Rails.env की जांच करते हैं, तो यह एक स्ट्रिंग की तरह व्यवहार करता है:

=> Rails.env "development" 

यहां स्ट्रिंग वही है जो RAILS*ENV एनवायरनमेंट वेरिएबल सेट है; यह _सिर्फ_ एक String नहीं है, हालांकि। कंसोल में क्लास पढ़ने पर, हम देखते हैं:

=> Rails.env.class ActiveSupport::StringInquirer 

Rails.env वास्तव में एक StringInquirer है।

StringInquirer

StringInquirer का कोड संक्षिप्त और अच्छी तरह से डॉक्यूमेंटेड है। यह कैसे काम करता है, हालांकि, स्पष्ट नहीं हो सकता है जब तक कि आप रूबी की मेटाप्रोग्रामिंग क्षमताओं से परिचित न हों। हम यहां क्या हो रहा है इसके माध्यम से चलेंगे।

class StringInquirer < String ... end 

सबसे पहले, हम देखते हैं कि StringInquirer String का एक सबक्लास है। यही कारण है कि जब हम इसे कॉल करते हैं तो Rails.env एक स्ट्रिंग की तरह व्यवहार करता है। String से इनहेरिट करके, हमें स्वचालित रूप से सभी स्ट्रिंग-जैसी कार्यक्षमता मिलती है, इसलिए हम इसे एक स्ट्रिंग की तरह ट्रीट कर सकते हैं। Rails.env.upcase काम करता है, जैसा कि ActiveRecordModel.find_by(string_column: Rails.env) करता है।

जबकि Rails.env StringInquirer का एक आसान, बिल्ट-इन उदाहरण है, हम अपने खुद के बनाने के लिए भी स्वतंत्र हैं:

def type result = "old" result = "new" if @new ActiveSupport::StringInquirer.new(result) end 

फिर, हमें वापस किए गए मान पर प्रश्न-चिह्न मेथड्स मिलते हैं:

=> @new = false => type.old? true => type.new? false => type.testvalue? false => @new = true => type.new? true => type.old? false 

method_missing

method_missing यहां असली सीक्रेट सॉस है। रूबी में, जब भी हम किसी ऑब्जेक्ट पर एक मेथड कॉल करते हैं, रूबी ऑब्जेक्ट के सभी पूर्वजों (यानी, बेस क्लासेस या शामिल मॉड्यूल्स) को मेथड के लिए देखना शुरू करता है। यदि कोई नहीं मिलता है, तो रूबी method_missing को कॉल करेगा, जिसमें उस मेथड का नाम पास किया जाएगा जिसे वह ढूंढ रहा है, साथ ही किसी भी आर्ग्यूमेंट्स के साथ।

डिफ़ॉल्ट रूप से, यह मेथड सिर्फ एक अपवाद उठाता है। हम सभी शायद NoMethodError: undefined method 'test' for nil:NilClass टाइप के एरर मैसेज से परिचित हैं। हम अपना खुद का method_missing इम्प्लीमेंट कर सकते हैं जो अपवाद नहीं उठाता, जो ठीक वही है जो StringInquirer करता है:

def method_missing(method_name, *arguments) if method_name.end_with?("?") self == method_name[0..-2] else super end end 

किसी भी मेथड नाम के लिए जो ? में समाप्त होता है, हम self के मान (यानी, स्ट्रिंग) की जांच मेथड नाम के बिना ? के विरुद्ध करते हैं। दूसरे शब्दों में, यदि हम StringInquirer.new("test").long_test_method_name? कॉल करते हैं, तो वापस किया गया मान "test" == "long_test_method_name" है।

यदि मेथड नाम नहीं प्रश्न चिह्न के साथ समाप्त होता है, तो हम मूल method_missing पर वापस आ जाते हैं (वह जो अपवाद उठाएगा)।

respond_to_missing?

फाइल में एक और मेथड है: respond_to_missing?. हम कह सकते हैं कि यह method_missing का एक साथी मेथड है। हालांकि method_missing हमें कार्यक्षमता देता है, हमें रूबी को यह बताने का एक तरीका भी चाहिए कि हम इन प्रश्न-चिह्न-समाप्त होने वाले मेथड्स को स्वीकार करते हैं।

def respond_to_missing?(method_name, include_private = false) method_name.end_with?("?") || super end 

यह तब काम आता है जब हम इस ऑब्जेक्ट पर respond_to? कॉल करते हैं। इसके बिना, यदि हम StringInquirer.new("test").respond_to?(:test?) कॉल करते हैं, तो परिणाम false होगा क्योंकि हमारे पास test? नामक कोई स्पष्ट मेथड नहीं है। यह स्पष्ट रूप से भ्रामक है क्योंकि मुझे उम्मीद होगी कि यह true वापस करेगा यदि मैं Rails.env.respond_to?(:test?) कॉल करता हूं।

respond_to_missing? वही है जो हमें रूबी से "हां, मैं उस मेथड को संभाल सकता हूं" कहने की अनुमति देता है। यदि मेथड नाम प्रश्न चिह्न में समाप्त नहीं होता है, तो हम सुपरक्लास मेथड पर वापस आ जाते हैं।

व्यावहारिक उपयोग के मामले

अब जब हम जानते हैं कैसे StringInquirer काम करता है, आइए उन उदाहरणों पर एक नज़र डालें जहां यह उपयोगी हो सकता है:

1. एनवायरनमेंट वेरिएबल्स

एनवायरनमेंट वेरिएबल्स दो मानदंडों को पूरा करते हैं जो उन्हें StringInquirer के लिए बेहतरीन विकल्प बनाते हैं। पहला, उनके पास अक्सर संभावित मानों का एक सीमित, ज्ञात सेट होता है (एक enum की तरह), और दूसरा, हमारे पास अक्सर सशर्त तर्क होता है जो उनके मान पर निर्भर करता है।

मान लें कि हमारा ऐप एक पेमेंट API से जुड़ा हुआ है, और हमारे पास क्रेडेंशियल्स एनवायरनमेंट वेरिएबल्स में स्टोर हैं। हमारे प्रोडक्शन सिस्टम में, यह स्पष्ट रूप से वास्तविक API है, लेकिन हमारे स्टेजिंग या डेवलपमेंट वर्जन में, हम उनके सैंडबॉक्स API का उपयोग करना चाहते हैं:

# ENV["PAYMENT_API_MODE"] = sandbox/production class PaymentGateway def api_mode # हम ENV.fetch का उपयोग करते हैं क्योंकि हम चाहते हैं कि यदि मान गायब है तो यह एरर उठाए @api_mode ||= ENV.fetch("PAYMENT_API_MODE").inquiry end def api_url # प्रो-टिप: हम *केवल* प्रोडक्शन का उपयोग करते हैं यदि MODE == 'production', और डिफ़ॉल्ट रूप से # सैंडबॉक्स पर अगर मान कुछ और है, यह हमें गलत टाइप या गलत मान होने पर प्रोडक्शन मानों का उपयोग करने से रोकता है if api_mode.production? PRODUCTION_URL else SANDBOX_URL end end end 

ध्यान दें कि उपरोक्त में, हम ActiveSupport के String#inquiry मेथड का उपयोग कर रहे हैं, जो आसानी से एक String को StringInquirer में परिवर्तित करता है।

2. API रिस्पॉन्स

ऊपर से हमारे पेमेंट API उदाहरण को जारी रखते हुए, API हमें एक रिस्पॉन्स भेजेगा जिसमें कुछ सफलता/विफलता स्थिति शामिल होगी। फिर से, यह उन दो मानदंडों को पूरा करता है जो इसे StringInquirer के लिए उम्मीदवार बनाते हैं: संभावित मानों का एक सीमित सेट और सशर्त तर्क जो इन मानों का परीक्षण करेगा।

class PaymentGateway def create_charge response = JSON.parse(api_call(...)) result = response["result"].inquiry if result.success? ... else ... end # result अभी भी एक स्ट्रिंग की तरह व्यवहार करता है Rails.logger.info("Payment result was: #{result}") end end 

निष्कर्ष

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

हालांकि यह StringInquirer पर केंद्रित है, यह लेख रूबी की कुछ मेटाप्रोग्रामिंग क्षमताओं का उपयोग करके method_missing के एक सौम्य परिचय के रूप में अधिक इरादा रखता है। मैं कहूंगा कि आप शायद अपने एप्लिकेशन में method_missing का उपयोग नहीं करना चाहते हैं। हालांकि, यह अक्सर फ्रेमवर्क्स में उपयोग किया जाता है, जैसे रेल्स या जेम्स द्वारा प्रदान किए गए डोमेन-स्पेसिफिक-लैंग्वेज, इसलिए जब आप मुद्दों का सामना करते हैं तो यह जानना बहुत मददगार हो सकता है कि "सॉसेज कैसे बनाया जाता है"।


  1. 7 शक्तिशाली Ruby Gems जिनके बारे में आपने शायद नहीं सुना होगा 7 शक्तिशाली Ruby Gems जिनके बारे में आपने शायद नहीं सुना होगा

    आपके Rails प्रोजेक्ट्स में उपयोग करने के लिए सबसे अच्छे Ruby gems क्या हैं? यही आप इस आर्टिकल में खोजेंगे! मैं आपको 7 gems देने जा रहा हूँ, लेकिन वही पुराने gems नहीं जिन्हें आपने लाखों बार देखा है, मैं आपके साथ कुछ ऐसे gems साझा करने जा रहा हूँ जो बहुत उपयोगी हैं, लेकिन कम ज्ञात हैं। लेकिन इससे पहल

  1. 2022 में गूगल प्ले स्टोर के टॉप 5 पुरस्कार-विजेता हिडन जेम ऐप्स 2022 में गूगल प्ले स्टोर के टॉप 5 पुरस्कार-विजेता हिडन जेम ऐप्स

    गूगल प्ले स्टोर पर प्रत्येक श्रेणी में लाखों ऐप्स हैं, चाहे वह गेमिंग हो, सोशल ऐप्स, ऑप्टिमाइज़ेशन या बैटरी सेवर ऐप्स। बहुत सारे अन्य ऐप्स हैं जो अन्य ऐप्स जितने लोकप्रिय नहीं हैं, लेकिन वे वास्तव में काम पूरा करने में मदद करते हैं और हम अक्सर उनका उपयोग करना पसंद करते हैं। हर दूसरे साल की तरह, गूगल

  1. विंडोज 11 मास्टर करें: विशेषज्ञ टिप्स और छिपी हुई सुविधाएं प्रकट विंडोज 11 मास्टर करें: विशेषज्ञ टिप्स और छिपी हुई सुविधाएं प्रकट

    विंडोज 11 संगत डिवाइस के लिए कई नई सुविधाओं और सुधारों के साथ मुफ्त अपग्रेड के रूप में उपलब्ध है। एक नया पुनः डिज़ाइन किया गया स्टार्ट मेनू टास्कबार, एंड्रॉइड ऐप सपोर्ट के साथ एक बेहतर माइक्रोसॉफ्ट स्टोर, एकीकृत माइक्रोसॉफ्ट टीम्स, स्नैप लेआउट, विजेट्स और बहुत कुछ है। लेकिन रेडमंड जायंट द्वारा आधिका