Ruby 构造函数中许多属性读取器的简写

Ruby 构造函数中许多属性读取器的简写,ruby,Ruby,我发现自己在类中初始化了很多变量,我想知道是否有更简单的方法来实现这一点。一旦你得到超过20个变量,它就变得有点多余了 class Car attr_reader :make, :model, :year, :id def initialize(args) @make = args["make"] @model = args["model"] @year = args["year"] @id = args["id"] e

我发现自己在类中初始化了很多变量,我想知道是否有更简单的方法来实现这一点。一旦你得到超过20个变量,它就变得有点多余了

class Car
  attr_reader :make, 
    :model, 
    :year, 
    :id

  def initialize(args)
    @make = args["make"]
    @model = args["model"]
    @year = args["year"]
    @id = args["id"]
  end
end

谢谢大家!

如果您特别关心
attr\u reader

class太空船翘曲9
ship.max_速度='299792458 m/s'#增加了NoMethodError

但是如果您对
attr\u访问器
没有问题,那么普通的
Struct
就可以了。

您也可以这样做:

class Car
  def initialize(args)
    args.each do |key, value|
      instance_variable_set("@#{key}", value)
    end
  end
end

car = Car.new({name: 'My car', make: 'BMW'})
p car #<Car:0x007fe80c8875d8 @name="My car", @make="BMW">
user = User.new(name: "Kasper")
user.name #=> "Kasper"
user.name = "Christina"
user.name #=> "Christina"
user.instance_variable_get(:@name) #=> "Christina"
等级车
def初始化(args)
args.each do |键、值|
实例变量集(“@#{key}”,值)
结束
结束
结束
car=car.new({name:'My car',make:'BMW'})
p车#

您可以使用一些动态技术,使您的代码具有灵活性,例如:

class Car
  def initialize(args = {})
    args.each do |ar|
      instance_variable_set(:"@#{ar.first}", ar.last)
    end
  end

  def method_missing(m, *args, &blk)
    if instance_variables.include? :"@#{m}"
      instance_variable_get("@#{m}")
    else
      super
    end
  end
end    
c = Car.new(foo: 1, bar: '132', baz: 'foo')    
puts c.foo
puts c.baz
puts c.bar    
puts c.barfoo
在irb中运行:

$ irb -r ./example.rb
#> 1
#> foo
#> 132
#> example.rb:14:in `method_missing': undefined method `barfoo' for #<Car:0x000000015bc740 @foo=1, @bar="132", @baz="foo"> (NoMethodError)
#> 1
#> foo
#> 132
#> #<Car:0x00000002dc1fc0 @foo=1, @bar="132", @baz="foo">
在irb中运行:

$ irb -r ./example.rb
#> 1
#> foo
#> 132
#> example.rb:14:in `method_missing': undefined method `barfoo' for #<Car:0x000000015bc740 @foo=1, @bar="132", @baz="foo"> (NoMethodError)
#> 1
#> foo
#> 132
#> #<Car:0x00000002dc1fc0 @foo=1, @bar="132", @baz="foo">
#>1
#>福
#> 132
#> #

再次在运行时为给定的键添加
attr\u reader
,并使用该键的值设置实例变量。

我忍不住写了一个gem来帮助实现这一点,因为我自己经常面临同样的烦恼。它叫“attr_args_速记”

基本上,在gem的帮助下,您可以这样做:

class User
  def initialize(args)
    AttrArgsShorthand.set(self, args)
  end
end
然后你可以这样做:

class Car
  def initialize(args)
    args.each do |key, value|
      instance_variable_set("@#{key}", value)
    end
  end
end

car = Car.new({name: 'My car', make: 'BMW'})
p car #<Car:0x007fe80c8875d8 @name="My car", @make="BMW">
user = User.new(name: "Kasper")
user.name #=> "Kasper"
user.name = "Christina"
user.name #=> "Christina"
user.instance_variable_get(:@name) #=> "Christina"

如果您发现自己经常创建20个左右的实例变量,并且在此基础上公开这些变量,那么您的设计决策就有问题。这只会设置一个实例变量,并在您尝试读取此处的一些变量时出错。我使用了此答案的一个变体。谢谢你给我指明了正确的方向。