ruby reduce duplication
class Car
attr_accessor :door, :window, :engine, :wheel, :mirror, :seat...
end
my_car = Car.new
开发者_开发知识库my_car.door, my_car.window, my_car.engine, my_car.wheel = "door", "window", "engine", "wheel"
I don't want to repeatedly type my_car
. I know I can define initialize(door, window, engine, wheel)
, but is there other way to do that? Something like
my_car.METHOD do
door, window, engine, wheel = "door", "window", "engine", "wheel"
end
You can do this in the constructor:
class Car
attr_accessor :door, :window, :engine, :wheel, :mirror
def initialize(opts={})
opts.each {|k,v| self.send("#{k}=", v)}
end
end
Then you can provide all the options at object creation time:
my_car = Car.new(:door => "4dr", :engine => "2.4L")
p my_car
#<Car:0x8a585f4 @door="4dr", @engine="2.4L">
For the question part of 'is there are any other way':
This form
my_car.METHOD do
door, window, engine, wheel = "door", "window", "engine", "wheel"
end
is similar to the instance_eval which evaluates block in the context of an object:
my_car.instance_eval do
@door = "door"
@window = "window"
end
P.S. Not arguing whether it's the best way, though :)
%w(door window) |f|
my_car.send(f + "=", "some string, possibly f itself like the next line")
my_car.send(f + "=", f)
end
Maybe facets can help you: Module.assign
Then this will be:
my_car.assign( :door => "door", :window => "window" .... )
You can actually define a yield initialize:
def initialize(&block) instance_eval(&block) end
Then
my_car = Car.new do @door = "door" @window = "window" #... end
The fact you have to use @attr, is because that statement like "var = value" will assume you set a new local variant.
精彩评论