使用块而不是构造函数参数来初始化对象

时间:2019-05-03 21:56:20

标签: ruby object

我有一个带有构造函数的类,该构造函数带有两个参数并将字段设置为这些值。我还希望能够通过在传递给构造函数的块内显式设置字段来初始化此类的对象。

构造函数:

class Grammar
    attr_reader :rules, :start, ...
    def initialize(rules, start)
        @rules = rules
        @start = start
        ...
    end
end

传递给构造函数的参数涉及创建多个对象,这些对象仅用作参数rulesstart的中间构建块,将这些对象的存在限制为块是有意义的传递给构造函数。在这一部分中,我希望首先构建中间对象,然后直接设置新对象的字段。

我希望能够像这样实例化Grammar

grammar = Grammar.new { |g|
    ...
    # build rules and start
    ...
    g.start = start
    g.rules = rules
}

如何修改构造函数以允许两种初始化方法?

2 个答案:

答案 0 :(得分:5)

向大多数类中添加此功能实际上非常容易,只要它们已经具有attr_writer和/或attr_accessor

class Grammar
  attr_accessor :rules, :start, ...

  def initialize(rules, start)
    @rules = rules
    @start = start
    ...

    yield self if block_given?
  end
end

您现在可以在其中完全按照自己的意愿进行操作。 yield self部分将提供要初始化的对象到块,并且block_given?仅在true调用中提供了块。设置所有默认值后,您将要运行此程序。

答案 1 :(得分:2)

您可能正在寻找内置在Ruby中的Object#Tap-将self屈服于块,然后返回self。

class Person
  attr_accessor :name 
end

person = Person.new.tap do |p|
  p.name = "Jan"
end

puts person.name # hi