当setter方法是使用attr_accessor方法动态生成的时,有没有更好的方法来设置值?我需要它来从Rails中的另一个模型为它们设置值。我正在试着做一些类似下面的事情。
attr_accessor
Model_class.all.each do |mdl| attr_accessor(mdl.some_field) end
然后我知道它创建了一组get和setter方法。我想做的是,当创建这些方法时,我希望为setter方法指定一些值。提前谢谢。
uxhixvfz1#
attr_accessor没有嵌入魔法。对于传递给它的每个参数,它基本上执行如下所示的操作(代码被简化并且缺少必要的检查等):
def attr_accessor(*vars) vars.each do |var| define_method var { instance_variable_get("@#{var}") } define_method "#{var}=" { |val| instance_variable_set("@#{var}", val) } end end
这就是说,attr_accessor :var1, :var2 DSL只是带来了新的4种普通的、老的、好的Ruby方法。对于您所问的问题,您可能需要注意定义这些方法(或者其中一些,或者一个都不定义)本身。例如,对于带有支票的繁琐设置,人们可能会这样做:
attr_accessor :var1, :var2
attr_reader :variable # reader is reader, no magic def variable=(val) do raise ArgumentError, "You must be kidding" if val.nil? @variable = val end
上面的代码和往常一样被称为:
instance.variable = 42 # ⇒ 42 instance.variable = nil # ⇒ ArgumentError: You must be kidding
chhkpiq42#
以下是这方面的另一个可能实现:
def attr_accessor(*args) args.each do |attribute| define_method(attribute.to_sym) { eval("@#{attribute}") } define_method((attribute.to_s + '=').to_sym) {|value| eval("@#{attribute} = value") } end end
2条答案
按热度按时间uxhixvfz1#
attr_accessor
没有嵌入魔法。对于传递给它的每个参数,它基本上执行如下所示的操作(代码被简化并且缺少必要的检查等):这就是说,
attr_accessor :var1, :var2
DSL只是带来了新的4种普通的、老的、好的Ruby方法。对于您所问的问题,您可能需要注意定义这些方法(或者其中一些,或者一个都不定义)本身。例如,对于带有支票的繁琐设置,人们可能会这样做:上面的代码和往常一样被称为:
chhkpiq42#
以下是这方面的另一个可能实现: