【问题标题】:Behavior of 'return' keyword within a ruby blockruby 块中“return”关键字的行为
【发布时间】:2011-08-09 15:36:47
【问题描述】:

有人可以解释以下行为

def iterate
  return yield
  return "end of iterate"
end

def test_iterate
  assert_equal( "end of iterate",  iterate { return "end of block" } )
  assert_equal( "end of block",  iterate { "end of block" } )
end

我知道 Procs(块是什么)应该在它们被调用的范围内返回。 (与 lambdas 不同)考虑到这一点,测试中的两个调用不应该返回“块结束”吗?

此测试通过 'ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]' (OSX 10.6.7)

【问题讨论】:

  • 这是否意味着return 从您的测试函数返回,使其在没有达到断言的情况下通过?
  • 确实如此。 '1 个测试,0 个断言,0 个失败,0 个错误'
  • 那么您第二次拨打iterate...
  • 我测试了 1.8.7 和 1.9.2,但都没有达到预期的第一个 assert_equal,因为您的第一个块中的 return 从该方法返回。
  • 正确,这是我的一个简单疏忽。 Hammar 正确地说明了第一个测试中的 return 语句退出了 'test_iterate' 块。尽管看起来测试通过了,但实际上测试从未完成。

标签: ruby lambda yield proc-object


【解决方案1】:

return 关键字从词法封闭方法返回。也就是说,*test_iterate*。

要以动态范围的方式从块中返回某个值,您应该改用 break 关键字。

在你的情况下:

iterate { break("end of block") }

测试将失败。因为 iterate 方法的第二个 return 语句永远不会运行。

应通过使用异常来实现预期的语义:

def iterate
  return yield
  rescue :exception
    return "end of iterate"
end

def test_iterate
  assert_equal( "end of iterate",  iterate { raise :exception } )
  assert_equal( "end of block",  iterate { "end of block" } )
end

【讨论】:

  • 这是允许测试通过的可接受方式。答案被接受。
猜你喜欢
  • 2014-03-09
  • 1970-01-01
  • 2014-12-24
  • 2017-09-16
  • 2016-03-11
  • 2013-09-24
  • 2019-11-07
  • 2019-02-22
  • 1970-01-01
相关资源
最近更新 更多