Ruby包含模块';s模型中的单一方法
我有一个下面的模块Ruby包含模块';s模型中的单一方法,ruby,methods,module,include,Ruby,Methods,Module,Include,我有一个下面的模块 module SimpleTask def task1 end def task2 end def task3 end end 我有一个模型,它只需要模块SimpleTask的task2方法 我知道在我的模型中包含include SimpleTask可以完成这项工作 但我想知道我是否只能在我的模型中包含特定的task2方法。听起来您需要将#task2重构为一个单独的模块(例如,BaseTask)。然后,您可以轻松地只在只需要#
module SimpleTask
def task1
end
def task2
end
def task3
end
end
我有一个模型,它只需要模块SimpleTask
的task2
方法
我知道在我的模型中包含include SimpleTask
可以完成这项工作
但我想知道我是否只能在我的模型中包含特定的
task2
方法。听起来您需要将#task2
重构为一个单独的模块(例如,BaseTask
)。然后,您可以轻松地只在只需要#task2
的位置包含BaseTask
module BaseTask
def task2
...
end
end
module SimpleTask
include BaseTask
def task1
...
end
def task3
...
end
end
如果没有更具体的问题(如SimpleTask
方法之间的相互依赖性等),很难提供更多帮助
你可以做一些元编程,包括SimpleTask,然后取消定义你不想要的方法,但是在我看来,这很难看。你可以添加
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
但在这种情况下,您必须更改所有呼叫者。我将从中窃取一个示例,它限制了它所包含的内容
...
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
...
您可以随时将其翻转,使其变为“仅包含”,而不是“包含”
问题是,remove_方法不适用于嵌套模块,使用undef将阻止在整个层次结构中搜索该方法。一个简单的解决方案是
define_方法:task2,SimpleTask.instance_方法(:task2)
可能重复的问题没有什么问题,这是一个好问题,而且非常清楚。我进入本页是因为我有完全相同的问题。我不想创建新模块,也不想不必要地在类命名空间中包含其他方法。我只想从模块中包含一个方法。mo只要所有模块实例方法都是私有的,dule_函数就很好。如果您希望它们是公共的,可以使用extend self
。必须注意的是,所有方法都不依赖于包含它们的实例的状态;在这种情况下,类方法将无法工作。
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]