Gag*_*gan 14 ruby methods module include
我有一个以下的模块
module SimpleTask
def task1
end
def task2
end
def task3
end
end
Run Code Online (Sandbox Code Playgroud)
我有一个只需要task2模块方法的模型SimpleTask.
我知道包括SimpleTask在我的模型中include SimpleTask可以完成这项工作.
但我想知道我是否只能task2在我的模型中包含特定方法.
听起来你需要重构成#task2一个单独的模块(例如BaseTask).然后,您可以轻松地只包含BaseTask您需要的地方#task2.
module BaseTask
def task2
...
end
end
module SimpleTask
include BaseTask
def task1
...
end
def task3
...
end
end
Run Code Online (Sandbox Code Playgroud)
没有更具体的问题(例如方法之间的相互依赖等),很难提供更多的帮助SimpleTask.
你可以在那里进行一些元编程,include SimpleTask然后取消定义你不想要的方法,但这是非常难看的IMO.
你可以添加
module SimpleTask
def task1
end
def task2
end
def task3
end
module_function :task2
end
Run Code Online (Sandbox Code Playgroud)
所以,你可以调用像模块上的类方法的方法以及具有其作为地方的实例方法你做到想所有这三种方法,即:
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
Run Code Online (Sandbox Code Playgroud)
或者,如果模块中确实没有共享状态,并且您不介意始终使用模块名称本身,则可以像这样声明所有方法类级别:
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
Run Code Online (Sandbox Code Playgroud)
但在这种情况下你必须改变所有的呼叫者.
我将从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
...
Run Code Online (Sandbox Code Playgroud)
变
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]
Run Code Online (Sandbox Code Playgroud)
你可以随时翻转它而不是包含它 include_only
问题是remove_method对嵌套模块不起作用,使用undef会阻止在整个层次结构中搜索该方法.