我似乎找不到办法做到这一点。 我想做的就是尝试第一个语句,如果它是空的或null(在任何阶段)然后返回另一个。例如
a.b.c.blank? ? a.b.c : 'Fill here'
这导致我nil:NillClass
例外。有没有办法以简单的单线方式解决这个问题?
答案 0 :(得分: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
之后,您可以使用它:
{{1}}
答案 1 :(得分:0)
默认情况下,没有nil:NilClass
异常抛出。
a
或b
或c
可能为零,因此对于单行语句,您可以执行以下操作:
# 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语句)
但这很难看,但如果您确定a
或a.b
永远不会nil
,则可以删除部分表达式。
我使用present?
而不是blank?
来保持与表达式相同的顺序。如果条件为真,则三元运算符计算第一个表达式,因此这可能是您的错误。
答案 2 :(得分:0)
我需要允许使用presence
的ActiveSupport包执行以下操作:
require 'active_support'
require 'active_support/core_ext/object/blank'
a.presence && a.b.presence && a.b.c.presence || 'Fill here'
答案 3 :(得分:0)
自 Ruby 2.3.0 (2015年12月25日发布)以来,可以使用save navigation operator
实现这一点,这类似于Groovy和Kotlin的null安全?
:
新方法调用语法,如果
object&.foo', method foo is called on
对象不是nil,则为{'1。
# 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