这可能是一个非常简单的问题,但我似乎无法在任何地方找到答案。我是Ruby 1.9的新手,用它来编写短脚本。
我的问题是如何在文件的顶层处理异常?是否真的有必要包含可能在begin / end子句中抛出异常的部分?
基本上我要做的是:
File.open( "foo" )
rescue Errno::EACCES => e
# Handle exception
答案 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