开发者

ruby reduce duplication

开发者 https://www.devze.com 2023-02-11 11:09 出处:网络
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\", \"engi
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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号