Reputation: 26264
[: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
It's giving the following error:
NoMethodError: undefined method `initial_amount_in_cents' for #<ViolationType:0x6220a88>
I tried to re-write it as:
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
But it gave me this error instead:
ERROR SystemStackError: stack level too deep
Upvotes: 2
Views: 99
Reputation: 84373
You have several, including:
Being DRY doesn't mean being obscure. If the code doesn't make sense to you the way it's written, refactor it for clarity.
The code is apparently trying to dynamically define an _in_cents
method for related methods that accept a float. You'd have to ask the author why he (or she) wrote it that way, but that's what it's for, whether or not it currently works for you.
With all that said, this may help. Assuming you have defined attributes in your model for initial_amount
and rate_increase_amount
then you should be able to simplify the call to Module#define_method. For example:
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
Upvotes: 2