在属性名称中使用插值(避免eval)



我正在定义自己的方法,该方法将允许我将给定对象的多个属性更新为另一个对象new_car的属性。许多属性具有类似的名称;entered_text_1"entered_text_2"entered_text_3";高达";entered_text_10";(在下面的例子中,我只做了3个例子来说明(。

问题

想知道如何在属性名称本身(如car.entered_text_"#{i}"(中使用插值(这是不正确的(

预期结果

下面的代码是有效的,并且符合我的要求,但是我已经看到了许多关于使用eval的警告,我想知道在这种情况下有什么更好的替代方案?

# 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

非常感谢!

您可以使用这样一个事实,即像user.name = 'John'这样的赋值实际上是方法调用,可以这样写:user.name=('John'),其中name=是方法的名称。我们可以用send(调用任何方法(或public_send(调用公共方法,如果方法存在但是私有的,则会引发错误(动态调用方法。

car.public_send("entered_text_#{i}=", new_car.public_send("entered_text_#{i}"))
puts car.public_send("entered_text_#{i}")

最新更新