2011-06-29 118 views
14

模塊的一個方法我有以下紅寶石包括在模型

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

的模塊,而且我只要求task2模塊SimpleTask的方法的典範。

我知道包括SimpleTask在我的模型中include SimpleTask會完成這項工作。

但我不知道我的模型中是否只能包含特定的task2方法。

+0

[我可以在不包含它的情況下調用Ruby模塊上的實例方法嗎?](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,然後取消定義你不想方法,但是這是很醜陋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將阻止在整個層次結構中搜索該方法。