我有两个例子:
第一:
class SomeClass
attr_accessor :some_var
def initialize
@some_var = 42
yield self if block_given?
end
end
p some_instance = SomeClass.new
another_instance = SomeClass.new do |s|
s.some_var = "foobar"
end
p another_instance
结果:
#<SomeClass:0x007fcdda047270 @some_var=42>
#<SomeClass:0x007fcdda047130 @some_var="foobar">
[Finished in 0.1s]
第二:
class SomeClass
attr_accessor :some_var
def initialize
@some_var = 42
yield self if block_given?
end
end
p some_instance = SomeClass.new
p another_instance = SomeClass.new do |s|
s.some_var = "foobar"
end
p another_instance
结果:
#<SomeClass:0x007fdd3f0131e0 @some_var=42>
#<SomeClass:0x007fdd3f0130a0 @some_var=42>
#<SomeClass:0x007fdd3f0130a0 @some_var=42>
[Finished in 0.1s]
我期待得到:
#<SomeClass:0x007fdd3f0131e0 @some_var=42>
#<SomeClass:0x007fcdda047130 @some_var=42>
#<SomeClass:0x007fcdda047130 @some_var="foobar">
[Finished in 0.1s]
我知道赋值比do … end块更贪婪.并且这些curlies比赋值更贪婪,如下所示:
第三:
p yet_another_instance = SomeClass.new { |s| s.some_var = "foobar" }
p yet_another_instance
结果:
#<SomeClass:0x007f9a420529c0 @some_var="foobar">
#<SomeClass:0x007f9a420529c0 @some_var="foobar">
但是第二个例子中的do … end块会发生什么?它不会被运行吗?
编辑:
接受@ max_pleaner的建议:)似乎Ruby完全忽略了它:
class SomeClass
attr_accessor :some_var
def initialize
@some_var = 42
yield self if block_given?
end
end
p some_instance = SomeClass.new
p another_instance = SomeClass.new do |s|
puts "cats and dogs?"
s.some_var = "foobar"
end
p another_instance
结果:
#<SomeClass:0x007fd01f96f130 @some_var=42>
#<SomeClass:0x007fd01f96eff0 @some_var=42>
#<SomeClass:0x007fd01f96eff0 @some_var=42>
[Finished in 0.1s]
所以现在我很好奇,在什么条件下Ruby完全忽略了一个块?有没有关于这种情况的文件?
编辑:
见接受的答案
class SomeClass
attr_accessor :some_var
def initialize
@some_var = 42
yield self if block_given?
end
end
p some_instance = SomeClass.new
p (another_instance = SomeClass.new do |s|
puts "cats and dogs?"
s.some_var = "foobar"
end)
p another_instance
结果:
#<SomeClass:0x007fcc6a043060 @some_var=42>
cats and dogs?
#<SomeClass:0x007fcc6a042f20 @some_var="foobar">
#<SomeClass:0x007fcc6a042f20 @some_var="foobar">
[Finished in 0.1s]
最佳答案 由于{…}和开始…结束的优先级不同而产生混淆,并且您不使用括号使其显式化.表达方式
p another_instance = SomeClass.new do |s|
puts "cats and dogs?"
s.some_var = "foobar"
end
被解释为
p(another_instance = SomeClass.new) do |s|
puts "cats and dogs?"
s.some_var = "foobar"
end
所以块传递给#p,而不是SomeClass #new.您可以明确强制执行其他订单:
p(another_instance = SomeClass.new do |s|
puts "cats and dogs?"
s.some_var = "foobar"
end)
这将以您期望的方式执行块.