如何在Ruby中初始化块中的类?

如何在Ruby中初始化块中的类?,ruby,Ruby,我想不出正确的块初始化 class Foo attr_accessor :bar end obj = Foo.new do |a| a.bar = "baz" end puts obj.bar 期待“baz” 相反,得到零 ruby中块类初始值设定项的正确咒语是什么?我认为new不能接受块。反正在哪儿也没见过。为什么要在块中初始化?如果你真的想要一个块,你总是可以执行obj=foo.new.tap do | a |…,实际上你有一个用于这些目的的构造函数: class Foo

我想不出正确的块初始化

class Foo 
  attr_accessor :bar
end

obj = Foo.new do |a|
  a.bar = "baz"
end

puts obj.bar
期待“baz” 相反,得到零


ruby中块类初始值设定项的正确咒语是什么?

我认为
new
不能接受块。反正在哪儿也没见过。为什么要在块中初始化?如果你真的想要一个块,你总是可以执行
obj=foo.new.tap do | a |…
,实际上你有一个用于这些目的的构造函数:

class Foo
  attr_accessor :bar

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

end
请重试:

class Foo 
  attr_accessor :bar
end

obj = Foo.new.tap do |a|
  a.bar = "baz"
end

puts obj.bar

创建块初始值设定项的另一种方法是自己编写一个:

class Foo
  attr_accessor :bar

  def initialize
    yield self if block_given?
  end
end

然后使用它:

foo = Foo.new do |f|
  f.bar = true
end


我的两分钱。

attr\u访问器不能以那种形式工作,并且块从未被调用。谢谢,你是对的,我修复了它,所以它现在是“功能性”代码。我知道它没有被调用(这解释了为什么它不工作)。我喜欢下面的“tap”概念,因为它让我可以使用像FactoryGirl这样的工具(需要默认的初始值设定项),而不必覆盖新的。你能举一个例子来说明
FactoryGirl
的用法吗?这里有一些关于这个问题的链接,并不是说它不能阻止,它只是丑陋。尽管如此,这是一个常见的“成语”。为什么它很丑?这是我在其他语言中使用过的一个常见的习语,比如c#。道格:在其他语言中它同样难看,主要原因是它没有任何特殊用途,只是增加了复杂性。我觉得它更清晰,更不容易出错。在普通构造函数中没有顺序依赖关系,您可以获得更易于读取和写入的命名参数。我可能只会求助于构造函数,如果除了复制值之外还有一些初始化(情况并非总是如此),也许你应该将其作为一个参数。Niklas,是的,那会更好。将它们作为构造函数传递并不常见。看看Github中的一些ruby代码,它们不一样。此外,它还应该引发一个
namererror
。这是不添加用户必须阅读文档的新方法的最佳方法。这种方法比在Foo的initialize方法中添加
yield self if block_给定?
要好,因为通常您不能或不想修改Foo类(想想开闭原则)。另外,为什么要把Foo类的initialize方法弄得乱七八糟,而一个简单的
tap
方法链接就可以了?毫无疑问,这是用块初始化类的更好方法。