在对this question用户的一个回答中,mu太短,说明您不希望对象的行为在初始化时发生太大的改变,这很有意义,您应该能够很好地推理出一个对象通过阅读其定义并进行内省,但我想到了这种情况:
french_colors.yml
blue: blue
red: rouge
...
translations.rb
class Translations
def initialize(language: "french")
data = YAML.load_file("./translations/#{language}.yml")
data.each do |k, v|
define_method k do
v
end
end
print_french_colors
end
def print_french_colors
puts red
puts blue
end
end
初始化后,上述错误与
#=> NoMethodError: undefined method `define_method' for #<C:0x2efae80>
在这里,您将从翻译公司收到的文件中构建所有Translations行为,并希望将其作为实例,并且还希望它基于语言文件是动态的(这只是一个示例)
在初始化中将转换定义和设置为对象的属性,而不是在OP和我试图这样做的初始化中使用define_method,是否更有意义?还是编写方法define_singleton_method
来专门处理这种情况?
答案 0 :(得分:0)
目前尚不清楚您的最终目标是什么。例如,如果语言不是法语,我不确定为什么会有print_french_colors
方法。看来您基本上是想读取yaml文件并使用它来设置一些预定义属性的值。
要做到这一点,我认为使用instance_variable_set而不是define_method会更有意义。这是一个例子。
french.yml
blue: blue
red: rouge
require "yaml"
class Translations
attr_reader :blue, :red
def initialize(language: "french")
data = YAML.load_file("#{language}.yml")
data.each do |k, v|
if respond_to?(k)
instance_variable_set("@#{k}",v)
else
puts "#{k} is not defined"
end
end
print_french_colors
end
def print_french_colors
puts red
puts blue
end
end
t = Translations.new
t.print_french_colors
答案 1 :(得分:-1)
回到您的问题...替换下面的代码块
define_method k do
v
end
使用
self.class.send(:define_method, k) do
v
end