【问题标题】:Catch exception from toplevel从顶层捕获异常
【发布时间】:2011-09-14 08:02:09
【问题描述】:

这可能是一个非常简单的问题,但我似乎无法在任何地方找到答案。我是 Ruby 1.9 的新手,我用它来编写简短的脚本。

我的问题是如何处理文件顶层的异常?真的有必要在开始/结束子句中包装可能引发异常的部分吗?

基本上我想要做的是:

File.open( "foo" )
rescue Errno::EACCES => e
    # Handle exception

【问题讨论】:

  • 你打算在异常处理中做一些有用的事情吗?如果没有,在简单的脚本中就可以让它爆炸。
  • 它是从串行连接收集数据的循环的一部分。我以为我的问题是串行端口,但实际上是 File.open 命令会失败。

标签: ruby exception-handling


【解决方案1】:

在这种情况下,您可能希望在打开文件之前检查是否存在,而不是挽救异常。

if File.exist?("foo.txt")
  File.open("foo.txt")
else
  abort("file.txt doesn't exist")
end

【讨论】:

  • 是的 - exceptional 事件例外。如果您希望文件偶尔不存在,请为不测事件编写代码。
  • 这似乎是一个完全让我无法理解的明显答案。谢谢。
【解决方案2】:

File.open 并没有做任何神奇的事情,本质上它只是 File.new 带有一个包裹在 begin/ensure 中的块,它会在块的末尾自动为你关闭文件,无论块是否正常结束,或者如果它内部发生了一些异常。

因此,您应该像处理 ruby​​ 代码的任何其他部分一样处理 File.open 的异常。 您可以让它滑动并让异常在其他地方处理(由异常处理程序链中的其他处理程序),或者您可以严格并当场处理它们。这个决定与 File.open 无关,它更多地与您的代码/应用程序和目标受众的性质有关。例如,如果您正在编写一个只能由您运行的脚本,那么让异常滑动并使用堆栈跟踪使脚本崩溃可能很好,在其他情况下,您可能希望更加“专业”并处理优雅地,在这种情况下,您必须在某些时候使用开始/救援。

这是希望揭开 File.open 神秘面纱的代码(它基本上只是在 Ruby 中实现 RAII idiom

File.open("foo") {|f|
  # do something with the opened file
  f.read

  # once the block has finished, the file will be closed automatically
}

# File.open is essentially:
f = File.new "foo"
begin
  yield f
ensure
  f.close
end

# So in any case if you'd like to handle any exception that might be raised, just do the usual thing:
begin
  File.open("foo") {|f|
    # do something with the opened file
    f.read
  }
rescue
  # handle all the exceptions - either coming from open/new or from inner file-handling block
end

begin
  f = File.new "foo"
  begin
    # do something with the opened file
    f.read
  ensure
    f.close
  end
rescue
  # handle the exceptions, using multiple rescue if needed to catch exact exception types like Errno::EACCES, etc
end

【讨论】:

  • 揭秘完成:)
猜你喜欢
  • 2021-08-20
  • 2016-03-13
  • 2013-10-15
  • 1970-01-01
  • 2011-05-07
  • 2021-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多