从顶层捕获异常

时间:2011-09-14 08:02:09

标签: ruby exception-handling

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

我的问题是如何在文件的顶层处理异常?是否真的有必要包含可能在begin / end子句中抛出异常的部分?

基本上我要做的是:

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

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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