Ruby check if nil before calling method

2020-02-20 07:11发布

问题:

I have a string in Ruby on which I'm calling the strip method to remove the leading and trailing whitespace. e.g.

s = "12345 "
s.strip

However if the string is empty I get the following error.

NoMethodError: undefined method `strip' for nil:NilClass

I'm using Ruby 1.9 so whats the easiest way to check if the value is nil before calling the strip method?

Update:

I tried this on an element in an array but got the same problem:

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

回答1:

Ruby 2.3.0 added a safe navigation operator (&.) that checks for nil before calling a method.

s&.strip

It will return nil if s is nil, rather than raising NoMethodError.



回答2:

You can use method try from ActiveSupport (Rails library)

gem install activesupport

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

or you can use my gem tryit which gives extra facilities:

gem install tryit

s.try { strip }


回答3:

If you don't mind the extra object being created, either of these work:

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

Without extra object:

s && s.strip
s.strip if s


回答4:

I guess the easiest method would be the following:

s.strip if s


回答5:

ActiveSupport comes with a method for that : try. For example, an_object.try :strip will return nil if an_object is nil, but will proceed otherwise. The syntax is the same as send. Cf active_support_core_extensions.html#try.



回答6:

Method which works for me (I know, I should never pollute pristine Object space, but it's so convenient that I will take a risk):

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) #=> "-"

In your particular case it could be:

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



回答7:

If you want to avoid the error that appears in the question:

s.to_s.strip


回答8:

Simply put:

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

Tl;dr Check if s is nil, then return s, otherwise, strip it.



回答9:

You could simply do this

s.try(:strip)


回答10:

I'd opt for a solution where s can never be nil to start with.

You can use the || operator to pass a default value if some_method returns a falsy value:

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

Or if s is already assigned you can use ||= which does the same thing:

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

Providing default scenario's for the absence of a parameters or variables is a good way to keep your code clean, because you don't have to mix logic with variable checking.



标签: ruby null