61

我在 Ruby 中有一个字符串,我在其上调用 strip 方法来删​​除前导和尾随空格。例如

s = "12345 "
s.strip

但是,如果字符串为 nil,我会收到以下错误。

NoMethodError: undefined method `strip' for nil:NilClass

我正在使用 Ruby 1.9 那么nil在调用 strip 方法之前检查值是否是最简单的方法是什么?

更新:

我在数组中的一个元素上尝试了这个,但遇到了同样的问题:

data[2][1][6].nil? ? data[2][1][6] : data[2][1][6].split(":")[1].strip
4

10 回答 10

121

Ruby 2.3.0添加了一个安全导航运算符( &.),它在调用方法之前检查 nil。

s&.strip

如果snil,则此表达式返回nil而不是 raise NoMethodError

于 2016-01-06T05:22:28.840 回答
17

您可以使用tryActiveSupport(Rails 库)中的方法

gem install activesupport

require 'active_support/core_ext/object/try'
s.try(:strip)

或者您可以使用我的 gem tryit,它提供了额外的功能:

gem install tryit

s.try { strip }
于 2012-09-14T14:27:07.290 回答
11

如果您不介意创建额外的对象,则可以使用以下任一方法:

"#{s}".strip
s.to_s.strip

没有额外的对象:

s && s.strip
s.strip if s
于 2012-09-14T16:39:21.020 回答
9

我想最简单的方法如下:

s.strip if s
于 2012-09-14T13:25:38.330 回答
3

我会选择一个s永远不可能nil开始的解决方案。

如果返回虚假值,您可以使用||运算符传递默认值:some_method

s = some_method || '' # default to an empty string on falsy return value
s.strip

或者,如果s已经分配,​​您可以使用||=which 做同样的事情:

s ||= '' # set s to an empty string if s is falsy
s.strip

为缺少参数或变量提供默认方案是保持代码干净的好方法,因为您不必将逻辑与变量检查混为一谈。

于 2019-09-22T23:47:24.067 回答
2

如果您想避免问题中出现的错误:

s.to_s.strip
于 2012-09-14T15:35:07.730 回答
2

ActiveSupport附带了一个方法:try。例如,如果为 nilan_object.try :strip则返回,否则将继续。语法与. 参见 active_support_core_extensions.html #trynilan_objectsend

于 2012-09-14T14:29:14.597 回答
2

适合我的方法(我知道,我不应该污染原始Object空间,但它非常方便,我会冒险):

class Object
  def unless_nil(default = nil, &block)
    nil? ? default : block[self]
  end
end

p "123".unless_nil(&:length) #=> 3
p nil.unless_nil("-", &:length) #=> "-"

在您的特定情况下,它可能是:

data[2][1][6].unless_nil { |x| x.split(":")[1].unless_nil(&:strip) }

于 2012-09-14T14:17:52.710 回答
1

要完成此处显示的选项,请使用 Ruby Style Guide 中推荐的“Existence Check Shorthand” :

用于&&=预处理可能存在或不存在的变量。Using&&=将仅在值存在时更改值 [意味着,不是nil],从而无需使用 . 检查其存在性if

所以在你的情况下,你会这样做:

s = "12345 "
s &&= s.strip
于 2020-05-25T20:57:43.810 回答
0

简单的说:

s = s.nil? ? s : s.strip

Tl;dr 检查 s 是否为 nil,然后返回 s,否则,剥离它。

于 2012-09-14T13:25:21.160 回答