2015-06-10 4 views
10

मैं github repo से कोड को समझने की कोशिश कर रहा हूं। यह ग्राहक स्थापित करने के लिए मणि का मुख्य मॉड्यूल है।मॉड्यूल `ClassMethods` को उसी नामस्थान में परिभाषित और विस्तारित क्यों किया गया?

module Github 
    # more code 
    class << self 
    def included(base) 
     base.extend ClassMethods # what would this be for? 
    end 
    def new(options = {}, &block) 
     Client.new(options, &block) 
    end 
    def method_missing(method_name, *args, &block) 
     if new.respond_to?(method_name) 
     new.send(method_name, *args, &block) 
     elsif configuration.respond_to?(method_name) 
     Github.configuration.send(method_name, *args, &block) 
     else 
     super 
     end 
    end 
    def respond_to?(method_name, include_private = false) 
     new.respond_to?(method_name, include_private) || 
     configuration.respond_to?(method_name) || 
     super(method_name, include_private) 
    end 
    end 

    module ClassMethods 
    def require_all(prefix, *libs) 
     libs.each do |lib| 
     require "#{File.join(prefix, lib)}" 
     end 
    end 
    # more methods ... 
    end 

    extend ClassMethods 
    require_all LIBDIR, 
    'authorization', 
    'validations', 
    'normalizer', 
    'parameter_filter', 
    'api', 
    'client', 
    'pagination', 
    'request', 
    'response', 
    'response_wrapper', 
    'error', 
    'mime_type', 
    'page_links', 
    'paged_request', 
    'page_iterator', 
    'params_hash' 

end 
  1. क्यों class << self और module ClassMethods इस्तेमाल किया है, और फिर class << self भाग में शामिल किए जाने के बजाय बढ़ा दिया?
  2. कक्षा वर्ग def included(base) है। ऐसा लगता है कि वर्ग विधियों को एक विशिष्ट वस्तु में जोड़ना है। यह इस तरह क्यों है? यह कक्षा की कार्यक्षमता से संबंधित हो सकता है, लेकिन मुझे समझ में नहीं आता है।

उत्तर

5
module MyModule 
    class << self 
    def included(base) 
     base.extend ClassMethods # what would this be for? 
    end 
    <...> 
    end 
    <...> 
end 

यह वास्तव में रूबी में एक बहुत ही आम प्रथा है। असल में, यह क्या कह रहा है: जब कुछ ऑब्जेक्ट include MyModule करता है, तो इसे extend MyModule::ClassMethods भी बनाएं। इस तरह की उपलब्धि उपयोगी है यदि आप एक मिश्रण चाहते हैं जो कुछ वर्गों को केवल वर्ग के उदाहरणों के लिए ही नहीं, बल्कि वर्ग के लिए भी जोड़ता है।

एक छोटी उदाहरण:

module M 
    # A normal instance method 
    def mul 
    @x * @y 
    end 

    module ClassMethods 
    # A class method 
    def factory(x) 
     new(x, 2 * x) 
    end 
    end 

    def self.included(base) 
    base.extend ClassMethods 
    end 
end 

class P 
    include M 
    def initialize(x, y) 
    @x = x 
    @y = y 
    end 

    def sum 
    @x + @y 
    end 
end 

p1 = P.new(5, 15) 
puts "#{p1.sum} #{p1.mul}" 

# Calling the class method from the module here! 
p2 = P.factory(10) 
puts "#{p2.sum} #{p2.mul}" 
+1

समझ में आता है कि। मैं विधि 'self.included (आधार)' के बारे में थोड़ा उलझन में हूं, क्या आप शायद यह बता सकते हैं कि यह क्या है और यह मॉड्यूल 'एम' या कक्षा 'पी' –

+4

से कैसे संबंधित है जब' पी 'कॉल' एम 'शामिल है, रूबी स्वचालित रूप से 'एम' पर 'शामिल' को कॉल करता है यदि इसे परिभाषित किया गया है। यह शामिल विधि का एक कॉलबैक है। इसका उपयोग मॉड्यूल की कक्षा विधियों को 'पी' पर बढ़ाने के लिए किया जाता है। देखें: http://ruby-doc.org/core-2.2.0/Module.html#method-i- शामिल – DGM

+0

क्या कोई मौका है कि आप मुझे इसके व्यावहारिक उदाहरण के लिए इंगित कर सकते हैं? मैं अभी भी उन परिस्थितियों पर स्पष्ट नहीं हूं जिनके लिए इसका उपयोग किया जाएगा। मुझे यकीन है कि मुझे इसे सही एप्लिकेशन समझने के लिए एक व्यावहारिक उदाहरण देखने की आवश्यकता है। –

1

repo में और अधिक खोज रहे हैं वहाँ एक और वर्ग Github::API है। इस वर्ग को Github::ClassMethods मॉड्यूल की कार्यक्षमता की आवश्यकता होती है।

module Github 
    # Core class responsible for api interface operations 
    class API 
    extend Github::ClassMethods 

तो यह है कि यह स्वयं के मॉड्यूल के मालिक हैं है समझ में आता है। यह केवल उन तरीकों को आयात करने की क्षमता देता है। यदि class << self के तरीकों को शामिल किया गया था, तो वे उपलब्ध हो जाएंगे जो शायद नहीं चाहते थे।

मॉड्यूल को अपनी कक्षा में रखना या कुछ और नाम देना बेहतर हो सकता है। लेकिन मुझे लगता है कि यह सिर्फ व्यक्तिगत पसंद है।

संबंधित मुद्दे