gpt4 book ai didi

从带有 ensure 的方法调用的 yield block 中返回 Ruby

转载 作者:数据小太阳 更新时间:2023-10-29 07:16:51 26 4
gpt4 key购买 nike

def foo
puts "in foo"
s = yield
puts "s = #{s}"
return 2
ensure
puts "in ensure"
return 1
end

def bar
foo do
puts "in bar block"
return 3
end
return 4
end


[36] pry(main)> r = bar
in foo
in bar block
in ensure
=> 4

我期望 r = 3,但结果是 r = 4。如果我删除确保代码,则期望 r = 3。这是为什么?

def foo
puts "in foo"
s = yield
puts "s = #{s}"
return 2
end

r = bar
in foo
in bar block
=> 3

最佳答案

这是从 block 中“展开堆栈”的 Ruby 功能。您的返回流程是如何逐步运作的:

  1. 你从 bar 返回 3堵塞。 return_value = 3 并且 Ruby 标记它是 block 的返回值,因此它应该展开堆栈并从父函数返回 3。它不会返回到 foo如果没有 ensure部分。从函数返回和从 block 返回是非常重要的区别。
  2. 但 Ruby 总是执行 ensure , 还有一个 returnensurefoo .
  3. return 1 之后在 ensurefoo , return_value是 1。它不是 block 中的值,所以 Ruby 会“忘记”之前的 return 3忘记从bar归还它.
  4. 它从 foo 返回 1和 4来自 bar .

另外,如果你写next 3而不是 return 3在 block 中 - 它将返回到 fooyield 之后并执行 puts "s = #{s}"; return 2即使没有确保 block 。这是迭代器和枚举器的神奇 Ruby 特性。

关于从带有 ensure 的方法调用的 yield block 中返回 Ruby,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29412201/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com