खोज…


टिप्पणियों

शोधन कार्यक्षेत्र हैं, जिसका अर्थ है कि वे उस समय से प्रभावी हैं जब तक कि वे पाली को नियंत्रित नहीं using (कीवर्ड का using )। आमतौर पर नियंत्रण एक मॉड्यूल, वर्ग, या फ़ाइल के अंत तक बदल दिया जाता है।

सीमित दायरे के साथ बंदर पैचिंग

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

module Patches
  refine Fixnum do
    def plus_one
      self + 1
    end

    def plus(num)
      self + num
    end

    def concat_one
      self.to_s + '1'
    end
  end
end

class RefinementTest
  # has access to our patches
  using Patches

  def initialize
    puts 1.plus_one
    puts 3.concat_one
  end
end

# Main scope doesn't have changes

1.plus_one
# => undefined method `plus_one' for 1:Fixnum (NoMethodError)

RefinementTest.new
# => 2
# => '31'

दोहरे उद्देश्य वाले मॉड्यूल (शोधन या वैश्विक पैच)

रिफाइनमेंट्स का उपयोग करके पैच को स्कोप करना एक अच्छा अभ्यास है, लेकिन कभी-कभी इसे विश्व स्तर पर लोड करना अच्छा होता है (उदाहरण के लिए विकास, या परीक्षण)।

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

module Patch
  def patched?; true; end
  refine String do
    include Patch
  end
end

# globally
String.include Patch
"".patched? # => true

# refinement
class LoadPatch
  using Patch
  "".patched? # => true
end

गतिशील शोधन

शोधन की विशेष सीमाएँ हैं।

refine केवल एक मॉड्यूल दायरे में उपयोग किया जा सकता है, लेकिन send :refine का उपयोग करके प्रोग्राम किया जा सकता है send :refine

using करना अधिक सीमित है। इसे केवल कक्षा / मॉड्यूल परिभाषा में कहा जा सकता है। फिर भी, यह एक मॉड्यूल की ओर इशारा करते हुए एक चर को स्वीकार कर सकता है, और एक लूप में आमंत्रित किया जा सकता है।

इन अवधारणाओं को दिखाने वाला एक उदाहरण:

module Patch
  def patched?; true; end
end

Patch.send(:refine, String) { include Patch }

patch_classes = [Patch]

class Patched
  patch_classes.each { |klass| using klass }
  "".patched? # => true
end

चूंकि using इतना स्थिर है, इसलिए लोड ऑर्डर के साथ जारी किया जा सकता है यदि शोधन फ़ाइलें पहले लोड नहीं की जाती हैं। इसका पता लगाने का एक तरीका यह है कि पैचेड क्लास / मॉड्यूल की परिभाषा को एक प्रॉप में लपेटा जाए। उदाहरण के लिए:

module Patch
  refine String do
    def patched; true; end
  end
end

class Foo
end

# This is a proc since methods can't contain class definitions
create_patched_class = Proc.new do
  Foo.class_exec do
    class Bar
      using Patch
      def self.patched?; ''.patched == true; end
    end
  end
end
create_patched_class.call
Foo::Bar.patched? # => true

Proc को कॉल करने से पैच क्लास Foo::Bar बनता है। सभी कोड लोड होने के बाद तक इसमें देरी हो सकती है।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow