之间有什么区别 - 技术,哲学,概念或其他方面
raise "foo"
和
raise Exception.new("foo")
答案 0 :(得分:115)
从技术上讲,第一个引发RuntimeError,消息设置为"foo"
,第二个引发异常,消息设置为"foo"
。
实际上,在您想要使用前者和何时想要使用后者之间存在显着差异。
简而言之,您可能想要RuntimeError
而不是Exception
。没有参数的救援区将捕获RuntimeErrors
,但不会捕获Exception
。因此,如果您在代码中引发Exception
,则此代码将无法捕获它:
begin
rescue
end
为了抓住Exception
,你必须这样做:
begin
rescue Exception
end
这意味着,从某种意义上说,Exception
是一个比“{1}}更糟糕”的错误,因为你必须做更多的工作才能从中恢复。
所以你想要的取决于你的项目如何处理错误。例如,在我们的守护进程中,主循环有一个空白的救援,它将捕获RuntimeError
,报告它们,然后继续。但是在一两种情况下,我们希望守护进程真的死于错误,在这种情况下,我们会引发一个RuntimeErrors
,直接通过我们的“正常错误处理代码”并将其输出。
同样,如果您正在编写库代码,您可能需要Exception
,而不是RuntimeError
,因为如果它引发空白{{1}的错误,您的库的用户会感到惊讶阻止无法捕获,并且需要花一点时间来实现原因。
最后,我应该说Exception
是rescue
类的子类,实际的规则是尽管你可以RuntimeError
任何类型对象,空白StandardError
默认只捕获从raise
继承的任何内容。其他一切都必须具体。
答案 1 :(得分:31)
From the offical documentation:
raise
raise( string )
raise( exception [, string [, array ] ] )
如果$!
为零,则在RuntimeError
中引发异常或引发$!
。使用单个String
参数,它会将字符串作为消息引发RuntimeError
。否则,第一个参数应该是Exception
类的名称(或者在发送异常时返回Exception
的对象)。可选的第二个参数设置与异常关联的消息,第三个参数是回调信息的数组。 begin...end
块的救援条款可以解除例外情况。
raise "Failed to create socket"
raise ArgumentError, "No parameters", caller