I'm defining my own method that will allow me to update multiple attributes of a given object to that of another object new_car
. Many of the attributes have similar names such as "entered_text_1", "entered_text_2", "entered_text_3" up to "entered_text_10" (In the example below I've just done up to 3 to illustrate).
Problem
Wondering how to use interpolation within an attribute name itself, such as car.entered_text_"#{i}"
(which is not correct)
Desired Outcome
The below code works and does what I'm looking for, however I've seen numerous warning about using eval
- and I'm wondering what the better alternative is in this scenario?
# class Car and class NewCar exist with the same attribute names (:entered_text_1, :entered_text_2, :entered_text_3)
def self.copy_attributes(car, new_car)
i = 1
until i > 3
eval("car.entered_text_#{i} = new_car.entered_text_#{i}")
puts eval("car.entered_text_#{i}")
i += 1
end
end
current_car = Car.new('White', 'Huge', 'Slow')
golf = NewCar.new('Red', 'Small', 'Fast')
copy_attributes(current_car, golf)
# => Red, Small, Fast
Many thanks!
You could use the fact that assignments like user.name = 'John'
are actually method calls and can be written like this: user.name=('John')
, where name=
is the name of the method. We can invoke methods dynamically with send
(call any method) or public_send
(call a public method, will raise error if method exists but is private).
car.public_send("entered_text_#{i}=", new_car.public_send("entered_text_#{i}"))
puts car.public_send("entered_text_#{i}")