带有异常处理的Ruby一行if语句

问题描述 投票:0回答:4

我似乎找不到办法做到这一点。我想做的就是尝试第一个语句,如果它是空的或null(在任何阶段)然后返回另一个。例如

a.b.c.blank? ? a.b.c : 'Fill here'

这导致我nil:NillClass例外。有没有办法以简单的单线方式解决这个问题?

ruby exception-handling ternary-operator
4个回答
2
投票

如果你有active_support可用,你可以使用Object#try

a.try(:b).try(:c) or 'Fill here'

如果你没有这个,那么很容易用Object来补充一个。这是active_support中的代码,在你使用try方法之前把它放在一些地方。

class Object
  def try(*a, &b)
    if a.empty? && block_given?
      yield self
    else
      public_send(*a, &b) if respond_to?(a.first)
    end
  end
end

之后,您可以使用它:

a = nil
a.try(:b).try(:c).try(:nil?)    #=> true

b = 1
b.try(:+, 2)    #=> 3

0
投票

默认情况下没有抛出nil:NilClass异常。

abc可能是零,所以对于单行声明,您可以这样做:

# require this to use present?, not needed with rails
require 'active_support/all'

a.present? ? (a.b.present? ? (a.b.c.present? ? a.b.c : 'Fill here') : 'Fill here') : 'Fill here'

(这是三元表达式,不完全是if语句)

但这很难看,虽然如果你确定aa.b永远不会是nil,你可以删除部分表达式。

我使用present?而不是blank?来保持与你的表达相同的顺序。如果条件为真,则三元运算符计算第一个表达式,因此这可能是您的错误。


0
投票

我需要允许使用presence的ActiveSupport包做类似这样的事情:

require 'active_support'
require 'active_support/core_ext/object/blank'
a.presence && a.b.presence && a.b.c.presence || 'Fill here'

见:http://apidock.com/rails/Object/presence


0
投票

从Ruby 2.3.0(2015-12-25发布)开始,这可以使用save navigation operator实现,类似于Groovy和Kotlin的null安全?

新方法调用语法,object&.foo', method foo is called onobject'如果它不是nil。

# a as object { b: { c: 'foobar' } }
a&.b&.c&.empty? ? 'Fill here' : a.b.c #=> 'foobar'
nil&.b&.c&.empty? ? 'Fill here' : a.b.c #=> 'Fill here'

当他们被调用nil对象时,安全调用返回nil。这就是为什么上面例子中的第二个案例评估为nil,因此false

来源:NEWS for Ruby 2.3.0 (Feature #11537) 另见:What is the difference between try and &. (safe navigation operator) in Ruby

© www.soinside.com 2019 - 2024. All rights reserved.