在控制台/rake/rails 中转义确保
Posted
技术标签:
【中文标题】在控制台/rake/rails 中转义确保【英文标题】:Escaping ensure in console/rake/rails 【发布时间】:2021-11-19 05:03:49 【问题描述】:鉴于这样的事情
def infinite
puts Time.now
rescue => err
puts err.message
ensure
infinite
end
当你在控制台/rake 中运行它并点击 ctrl-c - 没有任何反应。如何用 CTRL-C 转义?
【问题讨论】:
【参考方案1】:我不确定这是否是正确的解决方案,但这对我有用:
def infinite
puts Time.now
rescue SystemExit, Interrupt
@skip_ensure = true
puts 'SystemExist/Interrupt'
rescue => err
puts err.message
ensure
infinite unless @skip_ensure
end
【讨论】:
【参考方案2】:改用catch
,这是一种替代控制流。
catch 执行它的块。如果 throw 没有被调用,代码块会正常执行,catch 返回最后一个表达式的值。
Ruby 在它的堆栈中搜索一个 catch 块,它的标签与 throw 具有相同的 object_id(符号几乎总是被用作具有相同的 object_id)。找到后,该块停止执行并返回 val(如果没有给 throw 提供第二个参数,则返回 nil)。
def infinate
catch(:done) do
begin
infinite
rescue SystemExit, Interrupt => e
puts e.message
throw :done
end
end
end
将ensure
与这样的条件一起使用在语义上是错误的,因为确保的重点是运行始终应该运行的代码。
【讨论】:
【参考方案3】:使用rescue
通过递归创建无限循环似乎过于复杂,以后可能会导致SystemStackError
。
为什么不使用实际的loop
:
def infinite
loop do
begin
puts Time.now
rescue => err
puts err.message
end
end
end
使用上述方法,Ctrl-C 工作得很好,因为没有显式异常类的rescue
只会处理 StandardErrors。
【讨论】:
以上是关于在控制台/rake/rails 中转义确保的主要内容,如果未能解决你的问题,请参考以下文章