传递给新方法时do..end块会发生什么?

时间:2016-12-17 04:56:10

标签: ruby

我有两个例子:

第一

CircleMenuDelegate.circleMenu(**Circle Menu Object Here**, buttonWillSelected: UIButton, atIndex: Int)

结果:

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] 块更贪婪。并且这些curlies比赋值更贪婪,如下所示:

第三

do...end

结果:

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"> 块会发生什么?它不会被运行吗?

编辑:

接受@ max_pleaner的建议:)似乎Ruby完全忽略了它:

do...end

结果:

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

所以现在我很好奇,在什么条件下Ruby完全忽略了一个块?有没有关于这种情况的文件?

编辑:

参见接受的答案

#<SomeClass:0x007fd01f96f130 @some_var=42>
#<SomeClass:0x007fd01f96eff0 @some_var=42>
#<SomeClass:0x007fd01f96eff0 @some_var=42>
[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|
  puts "cats and dogs?"
  s.some_var = "foobar"
end)

p another_instance

1 个答案:

答案 0 :(得分:2)

由于{ ... }begin ... end的优先级不同而产生混淆,并且您不使用括号使其明确。表达式

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)

并且以您期望的方式执行该块。