[:initial_amount, :rate_increase_amount].each do |method|
define_method method do
self["#{method}_in_cents".to_sym].to_f/100 if self["#{method}_in_cents".to_sym]
end
define_method "#{method}=" do |_value|
self["#{method}_in_cents".to_sym] = _value.to_f * 100
end
end
它出现以下错误:
NoMethodError: undefined method `initial_amount_in_cents' for #<ViolationType:0x6220a88>
我试图将其重写为:
def initial_amount_in_cents
initial_amount_in_cents.to_f/100 if initial_amount_in_cents
end
def rate_increase_amount_in_cents
rate_increase_amount_in_cents.to_f/100 if rate_increase_amount_in_cents
end
def initial_amount= (value)
initial_amount_in_cents = value.to_f * 100
end
def rate_increase_amount= (value)
rate_increase_amount_in_cents = value.to_f * 100
end
但它给了我这个错误:
ERROR SystemStackError: stack level too deep
答案 0 :(得分:2)
你有几个,包括:
干燥并不意味着模糊。如果代码对你的编写方式没有意义,那么为了清晰起见重构它。
代码显然试图为接受float的相关方法动态定义_in_cents
方法。你必须问作者为什么他(或她)以这种方式写它,但这就是它的用途,无论它是否适合你。
尽管如此,这可能会有所帮助。假设您已在模型中为initial_amount
和rate_increase_amount
定义了属性,那么您应该能够简化对Module#define_method的调用。例如:
class YourRailsModel
%i[initial_amount rate_increase_amount].each do |method|
# You don't have a real Rails model here, so we create accessors to simulate
# model attributes.
attr_accessor method
define_method "#{method}_in_cents" do
Integer(Float send(method) * 100)
end
end
end
model = YourRailsModel.new
model.initial_amount = 0.97
# => 0.97
model.initial_amount_in_cents
# => 97