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

रूबी में 4 सरल संस्मरण पैटर्न (और एक रत्न)

संस्मरण एक ऐसी तकनीक है जिसका उपयोग आप अपने एक्सेसर विधियों को गति देने के लिए कर सकते हैं। यह उन तरीकों के परिणामों को कैश करता है जो समय लेने वाले काम करते हैं, ऐसे काम जिन्हें केवल एक बार करने की आवश्यकता होती है। रेल में, आप मेमोइज़ेशन को इतनी बार उपयोग करते हुए देखते हैं कि इसमें एक मॉड्यूल भी शामिल है जो आपके लिए विधियों को याद करेगा।

बाद में, यह विवादास्पद रूप से केवल वास्तव में सामान्य संस्मरण पैटर्न का उपयोग करने के पक्ष में हटा दिया गया था जिसके बारे में मैं पहले बात करूंगा। लेकिन जैसा कि आप देखेंगे, कुछ स्थान ऐसे हैं जहां यह मूल पैटर्न ठीक से काम नहीं करता है। इसलिए हम अधिक उन्नत संस्मरण पैटर्न को भी देखेंगे, और इस प्रक्रिया में रूबी के बारे में कुछ साफ-सुथरी बातें सीखेंगे!

सुपर बेसिक मेमोइज़ेशन

आप इस संस्मरण पैटर्न को रूबी में हर समय देखेंगे:

app/models/order.rb
class User < ActiveRecord::Base
  def twitter_followers
    # assuming twitter_user.followers makes a network call
    @twitter_followers ||= twitter_user.followers
  end
end

||= कमोबेश @twitter_followers = @twitter_followers || twitter_user.followers . इसका मतलब है कि आप केवल पहली बार twitter_followers . पर कॉल करने पर ही नेटवर्क कॉल करेंगे , और भविष्य की कॉल केवल आवृत्ति चर @twitter_followers . का मान लौटाएगी ।

बहु-पंक्ति संस्मरण

कभी-कभी, धीमा कोड एक पंक्ति में बिना भयानक काम किए फिट नहीं होता। कोड की कई पंक्तियों के साथ काम करने के लिए मूल पैटर्न का विस्तार करने के कुछ तरीके हैं, लेकिन यह मेरा पसंदीदा है:

app/models/order.rb
class User < ActiveRecord::Base
  def main_address
    @main_address ||= begin
      maybe_main_address = home_address if prefers_home_address?
      maybe_main_address = work_address unless maybe_main_address
      maybe_main_address = addresses.first unless maybe_main_address
    end
  end
end

begin...end रूबी में कोड का एक ब्लॉक बनाता है जिसे एक ही चीज़ के रूप में माना जा सकता है, जैसे {...} सी-शैली की भाषाओं में। इसीलिए ||= यहां ठीक वैसे ही काम करता है जैसे पहले किया करता था।

शून्य के बारे में क्या?

लेकिन इन संस्मरण पैटर्न में एक गंदी, छिपी हुई समस्या है। पहले उदाहरण में, क्या होगा यदि उपयोगकर्ता के पास ट्विटर खाता नहीं है, और ट्विटर अनुयायियों एपीआई ने nil लौटाया है ? दूसरे में, क्या होगा यदि उपयोगकर्ता के पास कोई पता नहीं है, और ब्लॉक nil returned लौटाता है ?

हर बार जब हम इस विधि को कॉल करेंगे, तो आवृत्ति चर nil होगा , और हम महंगे फ़ेच फिर से करेंगे।

तो, ||= शायद जाने का सही तरीका नहीं है। इसके बजाय, हमें nil . के बीच अंतर करना होगा और undefined :

app/models/order.rb
class User < ActiveRecord::Base
  def twitter_followers
    return @twitter_followers if defined? @twitter_followers
    @twitter_followers = twitter_user.followers
  end
end
app/models/order.rb
class User < ActiveRecord::Base
  def main_address
    return @main_address if defined? @main_address
    @main_address = begin
      main_address = home_address if prefers_home_address?
      main_address ||= work_address
      main_address ||= addresses.first # some semi-sensible default
    end
  end
end

दुर्भाग्य से, यह थोड़ा बदसूरत है, लेकिन यह nil . के साथ काम करता है , false , और सब कुछ। (nil को संभालने के लिए मामले में, आप इस समस्या से बचने के लिए अशक्त वस्तुओं और खाली सरणियों का भी उपयोग कर सकते हैं। nil avoid से बचने का एक और कारण !)

और पैरामीटर के बारे में क्या?

हमारे पास कुछ संस्मरण पैटर्न हैं जो साधारण एक्सेसर्स के लिए अच्छी तरह से काम करते हैं। लेकिन क्या होगा यदि आप एक ऐसी विधि को याद रखना चाहते हैं जो पैरामीटर लेती है, जैसे कि यह एक?

app/models/city.rb
class City < ActiveRecord::Base
  def self.top_cities(order_by)
    where(top_city: true).order(order_by).to_a
  end
end

यह पता चला है कि रूबी का Hash एक इनिटैलाइज़र है जो पूरी तरह से काम करता है इस स्थिति के लिए। आप Hash.new . पर कॉल कर सकते हैं एक ब्लॉक के साथ:

Hash.new {|h, key| h[key] = some_calculated_value }

फिर, हर बार जब आप हैश में एक कुंजी तक पहुंचने का प्रयास करते हैं जिसे सेट नहीं किया गया है, तो यह ब्लॉक को निष्पादित करेगा। और यह हैश को उस कुंजी के साथ पास कर देगा जिसे आपने ब्लॉक में एक्सेस करने का प्रयास किया था।

इसलिए, यदि आप इस विधि को याद रखना चाहते हैं, तो आप कुछ ऐसा कर सकते हैं:

app/models/city.rb
class City < ActiveRecord::Base
  def self.top_cities(order_by)
    @top_cities ||= Hash.new do |h, key|
      h[key] = where(top_city: true).order(key).to_a
    end
    @top_cities[order_by]
  end
end

और इससे कोई फर्क नहीं पड़ता कि आप order_by में क्या भेजते हैं , सही परिणाम याद हो जाएगा। चूंकि ब्लॉक केवल तभी कॉल किया जाता है जब कुंजी मौजूद नहीं होती है, इसलिए आपको ब्लॉक के शून्य या गलत होने के परिणाम के बारे में चिंता करने की आवश्यकता नहीं है।

आश्चर्यजनक रूप से, Hash उन कुंजियों के साथ ठीक काम करता है जो वास्तव में सरणियाँ हैं:

h = {}
h[["a", "b"]] = "c"
h[["a", "b"]] # => "c"

तो आप इस पैटर्न का उपयोग किसी भी पैरामीटर के साथ विधियों में कर सकते हैं!

इस सारी परेशानी से क्यों गुजरना है?

बेशक, यदि आप इन संस्मरण पैटर्न को कई तरीकों से जोड़ना शुरू करते हैं, तो आपका कोड बहुत जल्दी अपठनीय हो जाएगा। आपके तरीके सभी समारोह होंगे और कोई सार नहीं।

इसलिए यदि आप किसी ऐसे ऐप पर काम कर रहे हैं जिसके लिए बहुत अधिक संस्मरण की आवश्यकता है, तो हो सकता है कि आप एक ऐसे रत्न का उपयोग करना चाहें जो आपके लिए एक अच्छे, मित्रवत API के साथ संस्मरण को संभालता है। मेमोइस्ट एक अच्छा लगता है, और रेल के समान ही सुंदर है। (या, अपने नए-नए संस्मरण ज्ञान के साथ, आप स्वयं भी इसे बनाने का प्रयास कर सकते हैं)।

लेकिन इस तरह के पैटर्न की जांच करना हमेशा दिलचस्प होता है, देखें कि उन्हें एक साथ कैसे रखा जाता है, वे कहां काम करते हैं, और तेज किनारे कहां हैं। और जब आप एक्सप्लोर करते हैं तो आप कुछ कम ज्ञात रूबी सुविधाओं के बारे में कुछ साफ-सुथरी चीजें सीख सकते हैं।


  1. रुबोकॉप के साथ लाइनिंग और ऑटो-फॉर्मेटिंग रूबी कोड

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

  1. लॉगर और लॉगरेज के साथ रूबी में लॉगिंग

    रूबी में लॉग के साथ कार्य करना लॉगिंग उन प्राथमिक कार्यों में से एक है जिसे एक एप्लिकेशन आमतौर पर संबोधित करता है। लॉग का उपयोग तब किया जाता है जब आपको आवश्यकता होती है, उदाहरण के लिए, देखें कि आपके ऐप्स के अंदर क्या हो रहा है, उन पर नज़र रखें, या कुछ विशिष्ट डेटा के लिए मीट्रिक एकत्र करें। एक न

  1. रूबी जादू को कैसे दूर करें और अपने रत्नों को कैसे समझें

    जब आप रेल ऐप बनाते हैं, तो आप ढेर सारे रत्नों का उपयोग करेंगे। उनमें से कुछ पूरी तरह से जादुई लगते हैं! लेकिन यह जादू कैसे होता है? अधिकांश रत्नों में, वे ऐसा कुछ नहीं कर रहे हैं जो आप नहीं कर सकते। यह सिर्फ रूबी कोड है। कभी-कभी यह जटिल होता है रूबी कोड। लेकिन अगर आप उस कोड को एक्सप्लोर करते हैं, त