... SO
我有一个模块......
module Foo
class_methods do
def bar(*fields)
fields.each do |field|
define_method("set_#{field}=") do |value|
# nil check, other checks and validations
end
end
end
end
...这个模块将在我的应用程序中的几个模型中使用,但是现在我正在尝试测试它......
let(:entity_type) do
class TestClass
def initialize(value)
@field_value = value
end
include Foo
bar @field_value
self
end
end
let(:entity) { entity_type.new(:some_field) }
...但是,当我在测试中设置断点并查看实体的方法时,我只看到“set_ =”而不是“set_some_field =”,并且我尝试了几种使用符号,类实例变量的变体等等。非常感谢任何帮助!
答案 0 :(得分:1)
你的标题是“动态创建的类方法”,但看起来你实际上是动态创建实例类,也就是说,你可以有多个TestClass实例,每个实例都有自己的set_x =方法集合。这是你想要的吗?
假设是这样,您可以创建模块:
module Foo
def bar(*fields)
fields.each do |field|
define_method("set_#{field}=") do |value|
# nil check, other checks and validations
end
end
end
end
并像这样创建类:
class TestClass
extend Foo
def initialize(value)
@field_value = value
TestClass.bar(@field_value)
end
end
这样:t = TestClass.new("boop")
会使用方法t
为您提供实例类set_boop=()
。
我应该提一下,如果你创建另一个实例,它会有任何新的方法你给它以及之前实例中的所有先前方法。这是因为您正在使用每个实例修改类定义。
如果您不想要该功能,可以使用define_singleton_method并包含模块而不是扩展它,这使得bar成为设计用于创建其他实例方法的实例方法。你的课程看起来像这样:
module Foo
def bar(*fields)
fields.each do |field|
define_singleton_method("set_#{field}=") do |value|
# nil check, other checks and validations
end
end
end
end
class TestClass
include Foo
def initialize(value)
@field_value = value
bar(@field_value)
end
end
如果这不是你想要的,请告诉我,我会修改我的答案。