【问题标题】:Return false vs raising an exception in Ruby- When and why?在 Ruby 中返回 false 与引发异常 - 何时以及为什么?
【发布时间】:2014-05-22 19:01:41
【问题描述】:

我真的对以下概念感到困惑:

  • 不要将异常用作控制流
  • 不要将 nil/false 作为异常返回

假设我有以下实例方法:

class Logo
  # This method has some logic to create an image using Rmagick
  def process
    begin
      @logo_image = RmagickHelper.new(self.src)
    rescue Magick::ImageMagickError
      raise Exceptions::LogoUnprocessable, "ImageMagick can't process the URL"
    end
  end
end

所以在更一般的方法中,我有以下内容:

def build_all_images
    begin
      @logo.process
    rescue Exceptions::LogoUnprocessable
      @logo.status = 'unprocessable'
      return false #This terminates the method so no more stuff is processed, because logo could not be processed.
    end
#....
end

我的问题是:

这样做是否正确:

raise Exceptions::LogoUnprocessable, "ImageMagick can't process the URL"

或者我应该刚刚完成

return false

【问题讨论】:

标签: ruby-on-rails ruby exception-handling


【解决方案1】:

曾几何时,有一种语言没有异常构造 ()。每条消息都返回一个整数 - 0 表示成功或一些错误代码表示失败。如果调用者在继续之前没有检查返回码 - 他会被搞砸的。此外,大多数时候调用者对失败无能为力,所以即使他确实检查了结果 - 他可以做的唯一明智的事情就是返回自己的错误代码......

然后是 ,带有异常构造,仅用于这些用例。例外情况是该方法遇到无法处理的情况(例如读取不存在的文件,或在没有互联网连接的情况下上网)。

滥用 Exception 构造意味着在完全预期的情况下引发异常,例如:

def even?
  if (self % 2 != 0)
    raise NumberNotEvenException
  end
end

这里的奇数是合法的,也是预期的;抛出错误是滥用异常构造。

当方法不能完成它承诺的事情时抛出异常。

另一方面 - 当方法失败时返回 nilfalse 让我们回到快乐的 日子,此时调用者有责任注意到失败并找出问题所在- 不好玩。

【讨论】:

  • 因此,在我的情况下,我会提出异常,因为该图像的 SRC 不可访问(因为网页已关闭或无法作为图像打开)。这将是一个引发异常的好案例,对吧?
  • 是的,在这种情况下似乎有一个例外。
  • 可能没有直接关系,但是 Rails 中的 save 返回 falsesave! 抛出错误,所以这可能是在 Rails 中编码时需要考虑的事情。
【解决方案2】:

区别在于失败发生的频率以及它是否是一个简单的返回值。

询问“这是一个有效的 url”会期望一个“假”值,但在这种情况下,似乎当期望一个有效的 url 时,失败案例需要例外。

异常是“异常”或不寻常的。异常发生在命令方法中,您告诉它“执行此操作”并且它说“哎呀!”

流控制更多的是一个“这是什么”的问题,在这种情况下“哎呀”没有意义。

另外,请考虑调用代码的次数 - 处理异常需要比简单的返回值更多的时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-11
    • 2010-09-08
    • 1970-01-01
    • 2012-03-22
    • 2020-03-22
    • 1970-01-01
    • 2016-04-27
    • 2021-08-25
    相关资源
    最近更新 更多