在控制台/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 中转义确保的主要内容,如果未能解决你的问题,请参考以下文章

在 findstr 搜索字符串中转义引号

AWS Data Pipeline 在 emr 活动步骤部分中转义逗号

我应该在 Perl 中转义 shell 参数吗?

在 NVelocity 中转义 "

如何在 Presto 中转义单引号?

为啥必须在 XML 属性中转义 <?