我正在研究一个在类中提供常用功能的工具(称为Runner
),它可以使用一种插件系统调用用户定义的代码。对于该工具的任何执行,我需要动态地执行由一个或多个插件定义的各种方法。由于Runner
类定义了插件中将需要的许多实例级属性,我希望执行插件方法,就好像它们是实例方法的Runner
一样。如何动态调用模块方法,就像它是实例方法一样?
下面是一个简单的例子:
module Plugin1
def do_work
p ['Plugin1', data]
end
end
module Plugin2
def do_work
p ['Plugin2', data]
end
end
module Plugin3
def do_work
p ['Plugin3', data]
end
end
class Runner
attr_accessor :data # Plugins need access to these.
def initialize(data, *plugins)
@data = data
@plugin_names = plugins.map { |p| "Plugin#{p}" }
end
def run
@plugin_names.each { |name|
mod = Kernel.const_get(name)
plugin_method = mod.instance_method(:do_work)
# How do I call the plugin_method as if it were
# an instance method of the Runner?
}
end
end
# Execute a runner using Plugin3 and Plugin1.
r = Runner.new(987, 3, 1)
r.run
我曾与各种方式尝试去拉这个功能使用instance_exec
,bind
,module_function
,等等,但没有得到任何工作。当然,我对这个工具的其他方法持开放态度,但我也很好奇这是否可以按照上述方式完成。
我做了重大修改,一旦我想通了一些关于'包含'模块的细节。 –