2011-06-29 84 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将阻止在整个层次结构中搜索该方法。