2011-06-29 14 views
14

में मॉड्यूल के एकल विधि शामिल मैंरूबी मॉडल

module SimpleTask 
    def task1 
    end 
    def task2 
    end 
    def task3 
    end 
end 

निम्न में से एक मॉड्यूल है और मैं एक मॉडल है जो मॉड्यूल SimpleTask का केवल task2 विधि की आवश्यकता है है।

मुझे पता है कि मेरे मॉडल में include SimpleTask नौकरी करेगा।

लेकिन मुझे आश्चर्य है कि क्या मैं केवल अपने मॉडल में विशिष्ट task2 विधि शामिल कर सकता हूं।

+0

संभावित डुप्लिकेट [क्या मैं इसे शामिल किए बिना रूबी मॉड्यूल पर एक इंस्टेंस विधि का आह्वान कर सकता हूं?] (Http://stackoverflow.com/questions/322470/can-i-invoke-an-instance-method-on-a -ruby मॉड्यूल-बिना-सहित-यह) –

उत्तर

6

ऐसा लगता है कि आपको #task2 को एक अलग मॉड्यूल (उदाहरण के लिए, BaseTask) में दोबारा करने की आवश्यकता है। फिर आप आसानी से केवल BaseTask शामिल कर सकते हैं जहां आपको केवल #task2 की आवश्यकता है।

module BaseTask 
    def task2 
    ... 
    end 
end 

module SimpleTask 
    include BaseTask 

    def task1 
    ... 
    end 

    def task3 
    ... 
    end 
end 

यह (जैसे आदि SimpleTask के तरीकों के बीच अन्योन्याश्रय,

आप के रूप में एक और अधिक ठोस प्रश्न के बिना भी बहुत कुछ मदद करने के लिए मुश्किल है कर सकता है कुछ मेटा प्रोग्रामिंग जहां include SimpleTask और फिर undefine तरीकों आप नहीं करना चाहते हैं, लेकिन वह IMO बहुत बदसूरत है।

3

आप जोड़ सकते हैं

module SimpleTask 
    def task1 
    end 
    def task2 
    end 
    def task3 
    end 
    module_function :task2 
end 

ताकि आप मॉड्यूल पर एक वर्ग विधि की तरह विधि के रूप में अच्छी तरह से कॉल कर सकते हैं स्थानों में एक उदाहरण विधि आप कर के रूप में यह होने के रूप में चाहते हैं तीनों विधियों, अर्थात्:

class Foo 
    include SimpleTask 
end #=> Foo.new.task2 
class LessFoo 
    def only_needs_the_one_method 
     SimpleTask.task2 
    end 
end #=> LessFoo.new.only_needs_the_one_method 

या, यदि वहाँ वास्तव में मॉड्यूल में कोई भी साझा राज्य है और आप हमेशा कोई आपत्ति नहीं है मॉड्यूल का नाम ही है, तुम सिर्फ घोषणा कर सकते हैं तो जैसे सभी तरीकों वर्ग स्तरीय का उपयोग कर:

module SimpleTask 
    def self.task1 
    end 
    def self.task2 
    end 
    def self.task3 
    end 
end 

class Foo 
    include SimpleTask # Does, more or less nothing now 
    def do_something 
    SimpleTask.task1 
    end 
end 
#=> Foo.new.task2 #=> "task2 not a method or variable in Foo" 
#=> Foo.new.do_something does, however, work 
class LessFoo 
    def only_needs_the_one_method 
     SimpleTask.task2 
    end 
end #=> LessFoo.new.only_needs_the_one_method works as well in this case 

लेकिन आप सभी को बदलने के लिए होगा उस मामले में कॉलर्स।

5

मैं delegate.rb से एक उदाहरण चोरी करने के लिए जा रहा हूँ, यह प्रतिबंधित करता है यह क्या शामिल

... 
class Delegator < BasicObject 
    kernel = ::Kernel.dup 
    kernel.class_eval do 
    [:to_s,:inspect,:=~,:!~,:===,:<=>,:eql?,:hash].each do |m| 
     undef_method m 
    end 
    end 
    include kernel 
... 

हो जाता है

module PreciseInclude 

    def include_except(mod, *except) 
    the_module = mod.dup 
    the_module.class_eval do 
     except.each do |m| 
     remove_method m # was undef_method, that prevents parent calls 
     end 
    end 
    include the_module 
    end 
end 

class Foo 
    extend PreciseInclude 

    include_except(SimpleTask, :task1, :task2) 
end 

Foo.instance_methods.grep(/task/) => [:task3] 

आप हमेशा यह फ्लिप कर सकते हैं ताकि बजाय इसे include_only

हो जाता है शामिल

पकड़ यह है कि remove_method नेस्टेड मॉड्यूल के लिए काम नहीं करेगा, और undef का उपयोग करने से उस विधि के लिए पूरे पदानुक्रम को खोजना बंद हो जाएगा।

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