Ruby 中的 Proc 对象内的 return 到哪个级别?

To which level returns a return inside a Proc Object in Ruby?

据我了解,returnProc 中终止了当前方法。所以在下面的例子中我希望看到: a1 > b1 > 过程 > a2。但实际上它从来没有达到a2,为什么?

def a
  puts "a1"
  l = Proc.new {puts "proc"; return}
  b l
  puts "a2"
end

def b x
  puts "b1"
  x.call
  puts "b2"
end

a 

作为一般规则,return 总是 returns 来自 最近的词法封闭方法定义表达式 .

在这种情况下,最接近词法封闭的方法定义表达式是 def a,因此,return returns 来自 a.

在这种情况下,return 在块内实际上并不重要。一般规则是通用的,所以无论 return 出现在哪里,它都适用。

但是,如果我们更具体地查看块,我们会发现它仍然有意义:在块中,局部变量是词法捕获的,self 是词法捕获的,所以 return 也有词法行为。它是一个通用的属性块,如果你想了解一个块中发生了什么,你只需要从词法上向外看。

如果我们更具体一些,首先从一般规则到块,现在从块到 Procs,行为仍然有意义:Proc 本质上是一个具体化的块,因此 Proc 表现得像块是有意义的。

不过, 有一些例外一般规则,其中一个重要的例外是 lambdas。在 Ruby 中谈论 lambda 总是有点奇怪,因为 lambda 是 Proc,但它们的行为与 Proc 不同。 IMO,lambda 应该在 Proc 旁边有一个单独的 class。由于 lambda 是 Procs,所以谈论 lambdas 和 Procs 之间的区别是很奇怪的,它们不是 lambdas(它们没有标准化的名称,因此也被混淆地称为 Procs).

lambda 的行为不同于非 lambda 的行为 Proc 在两个方面,其中一个与您的问题相关:

  • 非 lambda 中的参数绑定 Procs 与块中的参数绑定具有相同的语义,而 lambda 中的参数绑定与消息发送/方法调用中的参数绑定具有相同的语义。
  • 在非 lambda Procs 中,return returns 来自最接近的词法封闭方法定义表达式,就像在块中一样,而在 lambda 中,return returns 来自 lambda 本身,就像方法中的 return

因此,在这两个方面,非 lambda Proc 表现得像块,而 lambda 表现得像方法。我是这样记的:“Proc”与“block”押韵,“lambda”和“method”都是希腊语。

您可能知道,有些方法也会改变传递给它们的块的行为。例如。 instance_evalinstance_exec 改变了 self 的值,而 define_method 实际上确实改变了 return.

的行为

但是由于你没有问一般的块,也没有具体问lambdas,而且你的问题中没有反射方法,所以一般规则仍然适用于非lambda Proc 就像您的问题中显示的那样:return returns 来自最接近的词法封闭方法定义表达式。