好的,让我们将问题分成两部分 - 获取此类方法的列表并在模块中制作代理。
获取列表可能有点棘手:
MyModule::UselessName.public_methods(false) - MyModule::UselessName.superclass.public_methods(false)
在这里,我们从所有公共类方法的列表开始,并从中减去所有超类的公共类方法的列表。
现在,假设我们知道方法的名称,我们需要创建代理方法。
metaclass = class << MyModule; self; end
metaclass.send(:define_method, :x) do |*args, &block|
MyModule::UselessName.send(:x, *args, &block)
end
此代码将在运行时等同于以下定义。
module MyModule
def x(*args, &block)
MyModule::UselessName.send(:x, *args, &block)
end
end
所以让我们把它放在一个简单的函数中。
def make_proxies(mod, cls)
methods = cls.public_methods(false) - cls.superclass.public_methods(false)
metaclass = class << mod; self; end
methods.each do |method|
metaclass.send(:define_method, method) do |*args, &block|
cls.send(method, *args, &block)
end
end
end
所以现在你只需要为需要的模块和类调用它。请注意,“目标”模块可能与拥有该类的“源”模块不同,因此您可以将所有方法(假设它们具有不同的名称,或者您将使用类名称作为前缀)添加到一个模块中。例如,对于您的情况,只需拨打以下电话。
make_proxies(MyModule, MyModule::UselessName)