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

रेल छिपे हुए रत्न:ActiveSupport StringInquirer

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

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

Rails.env हेल्पर

आप शायद पहले ही कोड देख चुके हैं जो रेल पर्यावरण की जांच करता है:

if Rails.env.test?
  # return hard-coded value...
else
  # contact external API...
end

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

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

=> Rails.env
"development"

यहाँ स्ट्रिंग वह है जो RAILS*ENV पर्यावरण चर पर सेट है; हालांकि, यह _just* एक स्ट्रिंग नहीं है। कंसोल में कक्षा पढ़ते समय, हम देखते हैं:

=> Rails.env.class
ActiveSupport::StringInquirer

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

StringInquirer

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

class StringInquirer < String
...
end

सबसे पहले, हम देखते हैं कि StringInquirer String का एक उपवर्ग है। यही कारण है कि Rails.env जब हम इसे कॉल करते हैं तो एक स्ट्रिंग की तरह कार्य करता है। स्ट्रिंग से इनहेरिट करके, हम स्वचालित रूप से सभी स्ट्रिंग जैसी कार्यक्षमता प्राप्त करते हैं, इसलिए हम इसे स्ट्रिंग की तरह व्यवहार कर सकते हैं। 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 . पर वापस आते हैं (वह जो अपवाद उठाएगा)।

response_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? . नामक कोई स्पष्ट विधि नहीं है . यह स्पष्ट रूप से भ्रामक है क्योंकि अगर मैं Rails.env.respond_to?(:test?) को कॉल करता हूं, तो मुझे उम्मीद है कि यह सच हो जाएगा। ।

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

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

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

1. पर्यावरण चर

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

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

# ENV["PAYMENT_API_MODE"] = sandbox/production

class PaymentGateway
  def api_mode
    # We use ENV.fetch because we want to raise if the value is missing
    @api_mode ||= ENV.fetch("PAYMENT_API_MODE").inquiry
  end

  def api_url
    # Pro-tip: We *only* use production if MODE == 'production', and default
    # to sandbox if the value is anything else, this prevents us using production
    # values if the value is mistyped or incorrect
    if api_mode.production?
      PRODUCTION_URL
    else
      SANDBOX_URL
    end
  end
end

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

2. एपीआई प्रतिक्रियाएं

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

class PaymentGateway
  def create_charge
    response = JSON.parse(api_call(...))

    result = response["result"].inquiry

    if result.success?
      ...
    else
      ...
    end

    # result still acts like a string
    Rails.logger.info("Payment result was: #{result}")
  end
end

निष्कर्ष

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

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


  1. 7 महान रूबी रत्न के बारे में ज्यादातर लोगों ने नहीं सुना है

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

  1. 2022 में Google Play Store के सर्वश्रेष्ठ छिपे हुए रत्न

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

  1. Windows 11 युक्तियाँ और छिपे हुए रत्न जिन्हें आपको जानना चाहिए

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