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

Jan*_*dło 3 ruby object

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

构造函数:

class Grammar
    attr_reader :rules, :start, ...
    def initialize(rules, start)
        @rules = rules
        @start = start
        ...
    end
end
Run Code Online (Sandbox Code Playgroud)

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

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

grammar = Grammar.new { |g|
    ...
    # build rules and start
    ...
    g.start = start
    g.rules = rules
}
Run Code Online (Sandbox Code Playgroud)

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

tad*_*man 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
Run Code Online (Sandbox Code Playgroud)

现在您可以在其中做您想要的一切。该yield self部件将把要初始化的对象提供给该块,并且block_given?true在您为new调用提供了一个块的情况下。设置所有默认值后,您将要运行此程序。