Ruby包含模块中模块的单一方法

我有一个以下模块

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

我有一个模型只需要模块SimpleTask task2方法。

我知道在我的模型中include SimpleTask可以完成这项工作。

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

听起来你需要将#task2重构为一个单独的模块(例如, BaseTask )。 然后,您可以轻松地只包含BaseTask ,只需要#task2

 module BaseTask def task2 ... end end module SimpleTask include BaseTask def task1 ... end def task3 ... end end 

没有更具体的问题(例如SimpleTask方法之间的相互依赖等),很难提供更多帮助。

可以执行一些元编程,其中include SimpleTask ,然后include SimpleTask定义您不想要的方法,但这是非常难看的IMO。

我要从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会阻止在整个层次结构中搜索该方法。

你可以添加

 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 

但是在这种情况下你必须改变所有的呼叫者。

一个简单的解决方案是

define_method :task2, SimpleTask.instance_method(:task2)