在ruby中创建惯用对象

gri*_*ton 14 ruby

在ruby中,我经常发现自己编写以下内容:

class Foo
  def initialize(bar, baz)
    @bar = bar
    @baz = baz
  end

  << more stuff >>

end
Run Code Online (Sandbox Code Playgroud)

甚至

class Foo
  attr_accessor :bar, :baz

  def initialize(bar, baz)
    @bar = bar
    @baz = baz
  end

  << more stuff >>

end
Run Code Online (Sandbox Code Playgroud)

我总是希望尽可能地减少样板 - 所以有没有更惯用的方式在ruby中创建对象?

Rai*_*kis 11

一个选项是您可以从Struct继承您的类定义:

class Foo < Struct.new(:bar, :baz)
  # << more stuff >>
end

f = Foo.new("bar value","baz value")
f.bar #=> "bar value"
f.baz #=> "baz value"
Run Code Online (Sandbox Code Playgroud)

  • 你也可以做`Foo = Struct.new(:bar,:baz)do ... end`而不是继承 (3认同)

saw*_*awa 10

我问了一个重复的问题,并在那里提出了我自己的答案,希望有一个更好的答案,但是没有出现令人满意的问题.我会张贴自己的.

定义一个类的方法等一起的精神下attr_accessor,attr_reader,attr_writer方法.

class Class
    def attr_constructor *vars
        define_method("initialize") do |*vals|
            vars.zip(vals){|var, val| instance_variable_set("@#{var}", val)}
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

然后,您可以像这样使用它:

class Foo
    attr_constructor :foo, :bar, :buz
end

p Foo.new('a', 'b', 'c')      # => #<Foo:0x93f3e4c @foo="a", @bar="b", @buz="c">
p Foo.new('a', 'b', 'c', 'd') # => #<Foo:0x93f3e4d @foo="a", @bar="b", @buz="c">
p Foo.new('a', 'b')           # => #<Foo:0x93f3e4e @foo="a", @bar="b", @buz=nil>
Run Code Online (Sandbox Code Playgroud)