【发布时间】:2018-03-06 15:03:19
【问题描述】:
在我的代码库中,我有一堆对象,它们都遵循同一个接口,其中包含如下内容:
class MyTestClass
def self.perform(foo, bar)
new(foo, bar).perform
end
def initialize(foo, bar)
@foo = foo
@bar = bar
end
def perform
# DO SOMETHING AND CHANGE THE WORLD
end
end
类之间的区别因素是self.perform 和initialize 的arity,加上#perform 类的主体。
所以,我希望能够创建一个 ActiveSupport::Concern(或者只是一个普通的 Module,如果这样会更好),它允许我做这样的事情:
class MyTestClass
inputs :foo, :bar
end
然后它会使用一些元编程来定义上述方法中的self.perform 和initialize,它们的airty 将取决于self.inputs 方法指定的airty。
这是我目前所拥有的:
module Commandable
extend ActiveSupport::Concern
class_methods do
def inputs(*args)
@inputs = args
class_eval %(
class << self
def perform(#{args.join(',')})
new(#{args.join(',')}).perform
end
end
def initialize(#{args.join(',')})
args.each do |arg|
instance_variable_set(@#{arg.to_s}) = arg.to_s
end
end
)
@inputs
end
end
end
这似乎使方法的 arity 正确,但我很难弄清楚如何处理 #initialize 方法的主体。
谁能帮我找出一种方法,让我可以成功地对#initialize 的主体进行元编程,使其表现得像我提供的示例一样?
【问题讨论】:
标签: ruby-on-rails ruby metaprogramming