【问题标题】:Dynamically defined setter methods using define_method?使用define_method动态定义的setter方法?
【发布时间】:2011-01-30 18:02:48
【问题描述】:
我使用大量迭代来在我的模型中定义便利方法,例如:
PET_NAMES.each do |pn|
define_method(pn) do
...
...
end
但我一直无法动态定义 setter 方法,即:
def pet_name=(name)
...
end
像这样使用define_method:
define_method("pet_name=(name)") do
...
end
有什么想法吗?提前致谢。
【问题讨论】:
标签:
ruby-on-rails
ruby
activerecord
metaprogramming
【解决方案1】:
这是一个相当完整的示例,在您用来扩展类的模块中使用 define_method:
module VerboseSetter
def make_verbose_setter(*names)
names.each do |name|
define_method("#{name}=") do |val|
puts "@#{name} was set to #{val}"
instance_variable_set("@#{name}", val)
end
end
end
end
class Foo
extend VerboseSetter
make_verbose_setter :bar, :quux
end
f = Foo.new
f.bar = 5
f.quux = 10
输出:
@bar 设置为 5
@quux 设置为 10
您很接近,但您不想将方法的参数包含在 调用 到 define_method 的参数中。参数进入您传递给define_method 的块中。
【解决方案2】:
如果您需要在一个类/模块中使用它:
我使用哈希,但你可以在那里放置元素数组等。
PETS = {
"cat" => "meyow",
"cow" => "moo",
"dog" => "ruff"
}
def do_smth1(v)
...
end
def do_smth(sound,v)
...
end
#getter
PETS.each{ |k,v| define_method(k){ do_smth1(v) } }
#setter
PETS.each{ |k,v| define_method("#{k}="){|sound| do_smth2(sound, v) }