【问题标题】:Ruby Oneline Rescue红宝石在线救援
【发布时间】:2013-03-13 21:26:44
【问题描述】:

我最近了解到,您可以在一行代码中使用rescue,以防该行出现问题(请参阅http://www.rubyinside.com/21-ruby-tricks-902.html 提示#21)。我有一些过去看起来像这样的代码:

if obj['key'] && obj['key']['key2'] && obj['key']['key2']['name']
  name = obj['key']['key2']['name']
else
  name = ''
end

使用rescue 方法,我相信我可以将代码改成这样:

name = obj['key']['key2']['name'] rescue ''

如果在访问哈希的任何级别引发 nil 异常,它应该被救援人员捕获并给我 '',这就是我想要的。如果这是所需的行为,我还可以选择将名称设置为 nil。

这样做有什么已知的危险吗?我问是因为这似乎好得令人难以置信。我有很多丑陋的代码,我很想摆脱它,看起来就像第一个代码示例。

【问题讨论】:

  • 对于特定用途,内联 rescue 是安全的。在方法调用结束时要非常小心使用它,否则可能会因为 I/O 错误或缺少数据库信息而引发异常。调试这些情况真的非常非常困难,而且会让你发疯。

标签: ruby rescue


【解决方案1】:

读起来不错!但它会影响你的表现。根据我的经验,rescue 在触发时要慢得多,而在未触发时则要慢一些。在所有情况下,if 都更快。另一件需要考虑的事情是,不应期望出现异常,并且您会使用此代码。拥有如此深嵌套的哈希可能是一种很好的气味,需要重构

【讨论】:

  • 哈希值来自返回深度嵌套 JSON 的 Web 服务。我必须一直检查 nil,因为该服务经常将嵌套元素保留为 nil。
  • 如果是这种情况,我建议您使用 gem 来增强您的哈希值,以使您的代码更具可读性:github.com/intridea/hashie。
  • 特别是 Mash (github.com/intridea/hashie#mash) 查看多级测试的示例,它可能不会比 ifs 更快,但它会改进您的代码!
【解决方案2】:

现在可以使用 Ruby 2.3 的 dig method 来实现这个特定示例。

name = obj.dig 'key', 'key2', 'name'

这将安全地访问obj['key']['key2']['name'],如果任何步骤失败则返回 nil。

(一般来说,通常建议仅对真实的、未预料到的错误使用异常,尽管在这样的示例中,如果语法使其变得麻烦,这是可以理解的。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 2014-08-21
    • 1970-01-01
    • 2013-06-23
    • 2018-10-30
    • 2018-10-09
    • 1970-01-01
    相关资源
    最近更新 更多