在 ruby 中,如何将 class 变量传递给混入模块动态创建的 class 方法?
In ruby, how to pass a class variable into a mixed-in module's dynamically created class method?
所以...
我有一个模块...
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=" 并且我尝试了几种使用符号的变体,class 实例变量等。非常感谢任何帮助!
你的标题说 "dynamically created class method" 但看起来你实际上是在动态创建实例 classes,即你可以有多个 TestClass 实例,每个实例都有自己的 collection 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:
class TestClass
extend Foo
def initialize(value)
@field_value = value
TestClass.bar(@field_value)
end
end
这样:t = TestClass.new("boop")
将使用方法 set_boop=()
.
为您提供实例 class t
我应该提一下,如果您创建另一个实例,它将具有您为其提供的任何新方法 以及 先前实例中的所有先前方法。这是因为您正在修改每个实例的 class 定义。
如果您不需要该功能,您可以使用 define_singleton_method 并包含模块而不是扩展它,这使得 bar 成为一个实例方法,旨在创建其他实例方法。您的 class 看起来像这样:
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
如果这不是您要找的,请告诉我,我会修改我的答案。
所以...
我有一个模块...
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=" 并且我尝试了几种使用符号的变体,class 实例变量等。非常感谢任何帮助!
你的标题说 "dynamically created class method" 但看起来你实际上是在动态创建实例 classes,即你可以有多个 TestClass 实例,每个实例都有自己的 collection 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:
class TestClass
extend Foo
def initialize(value)
@field_value = value
TestClass.bar(@field_value)
end
end
这样:t = TestClass.new("boop")
将使用方法 set_boop=()
.
t
我应该提一下,如果您创建另一个实例,它将具有您为其提供的任何新方法 以及 先前实例中的所有先前方法。这是因为您正在修改每个实例的 class 定义。
如果您不需要该功能,您可以使用 define_singleton_method 并包含模块而不是扩展它,这使得 bar 成为一个实例方法,旨在创建其他实例方法。您的 class 看起来像这样:
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
如果这不是您要找的,请告诉我,我会修改我的答案。