需要知道如何重构代码:
attr_accessor :product
attr_reader :name, :mark
def name=(value)
super unless product.present?
end
def mark=(value)
super unless product.present?
end
... and a whole bunch of method of sorts.
这个想法很简单 - 如果已经设置了产品,则拒绝分配值。但上面的代码根本就不是DRY。
有什么想法吗?
答案 0 :(得分:2)
attr_accessor :product
attr_reader :name, :mark
["name", "mark"].each do |method|
define_method("#{method}=") do |value|
super(value) unless product.present?
end
end
答案 1 :(得分:1)
您可以创建attr_*
等方法来处理此问题。这是通过重新打开Class
类并定义以下方法来完成的。
def attr_validator(*args)
#We simply iterate through each passed in argument...
args.each do |arg|
# Create an attr_reader
self.class_eval("
def #{arg};
@#{arg};
end
")
# Here we hardcode "product" since this every attribute
# checks itself against this object
self.class_eval("
def #{arg}=(val);
super unless product.present?;
end
")
end
end
通过这种方式,我们摆脱了向预处理器方法(在我的情况下,attr_validator
)附加属性的冗余,以及用于元编程目的的不同数组。
因此可以使用......
attr_accessor :product
attr_validator :name, :mark, :price, :stock # ...and so on