Ruby中的fail关键字是什么作用?

93

我正在学习Ruby,遇到了fail关键字。它是什么意思?

if password.length < 8
   fail "Password too short"
end
unless  username
   fail "No user name set"
end

10
除了下面的回答之外,值得知道的是人们在处理异常时使用“raise”,而在没有处理异常时使用“fail”。 - Bala
6
不是关键字,而是方法。 - Jörg W Mittag
文档:Kernel#fail - Jared Beck
还要注意,你可以将它们写成单行语句:fail "密码太短" if password.length < 8fail "未设置用户名" unless username - PhilT
4个回答

145

在Ruby中,failraise是同义词。 fail关键字是Kernel模块的一个方法,其中包括类Objectfail方法像raise关键字一样引发运行时错误。

fail方法有三种重载:

  • fail:引发一个没有错误消息的RuntimeError异常。

  • fail(string):引发一个带有字符串参数作为错误消息的RuntimeError异常:

    fail "Failed to open file"
    
  • fail(exception [, string [, array]]):抛出一个指定类exception的异常(第一个参数),并可选地包括错误消息(第二个参数)和回调信息(第三个参数)。

    例如:假设你定义了一个函数,如果给定了错误的参数,则应该失败。最好引发ArgumentError而不是RuntimeError

    fail ArgumentError, "Illegal String"
    

    另一个例子:你可以将整个回溯信息传递给fail方法,以便在rescue块中访问该跟踪:

    fail ArgumentError, "Illegal String", caller
    

    caller 是一个 Kernel 方法,它以 file:line: in 'method' 的形式将回溯信息作为字符串数组返回。

    当没有参数时,会抛出 $! 中的异常或者如果 $! 为空则抛出 RuntimeError 异常。当只有一个字符串参数时,会使用该字符串作为消息抛出 RuntimeError 异常。否则,第一个参数应该是 Exception 类的名称(或一个发送异常消息时返回 Exception 对象的对象)。可选的第二个参数设置与异常关联的消息,第三个参数是一个回调信息数组。异常可以被 begin...end 块的 rescue 子句捕获。

    来源:Kernel 模块的 Ruby 文档


2
你能给出三个简单的例子来说明这三个要点吗?这样会让你的回答更加具体。 :) - Arup Rakshit
1
哇,+1,crazybob的文档比Ruby官方文档还好 http://ruby-doc.org/core-2.0.0/Kernel.html#method-i-raise :-))) - Boris Stitnicky
它对我有效,但 Rubocop 将其转换为 raise - paul

33

Rubocop 建议在引发异常时使用 fail 代替 raise

当重新抛出异常时,请使用 raise 代替 fail

以下是一个示例:

def sample
  fail 'something wrong' unless success?
rescue => e
  logger.error e
  raise
end

+1 的风格建议:即使在语义上它们相同,使用每个词可以更好地传达意图。 - fatuhoku
很遗憾,链接已经失效了。 - Lindydancer
1
他们似乎更新了指南。在撰写本文时:对于异常情况,优先使用raise而不是fail。 - matmat

26

fail == raise

换句话说,fail只是raise错误抛出方法的一个常用别名。使用方法如下:

fail ArgumentError, "Don't argue with me!"

7

www.ruby-doc.org是你的好朋友。当我谷歌搜索rubydoc fail时,"Kernel"是第一个搜索结果。我的建议是,在怀疑时,去这个权威定义来源进行定义性的查询。


2
哇,这真的是一个失败。Fail 的代码示例是从 raise o_O 复制粘贴的。 - Vajk Hermecz
4
@VajkHermecz 中的 fail 是 raise 的别名,因此它重用了文档。请参考 Array#map 和 Array#collect 的文档进行比较。 - Jamie Macey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接