Ruby check if nil before calling method

RubyNull

Ruby Problem Overview


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 nil 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

Ruby Solutions


Solution 1 - Ruby

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

s&.strip

If s is nil, this expressions returns nil instead of raising NoMethodError.

Solution 2 - Ruby

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 }

Solution 3 - Ruby

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

Solution 4 - Ruby

I guess the easiest method would be the following:

s.strip if s

Solution 5 - Ruby

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.

Solution 6 - Ruby

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) }

Solution 7 - Ruby

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.

Solution 8 - Ruby

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

s.to_s.strip

Solution 9 - Ruby

To complete the options shown here, there is the "Existence Check Shorthand", recommended in the Ruby Style Guide:

> Use &&= to preprocess variables that may or may not exist. Using &&= will change the value only if it exists [means, is not nil], removing the need to check its existence with if.

So in your case you would do:

s = "12345 "
s &&= s.strip

Solution 10 - Ruby

Simply put:

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

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1513388View Question on Stackoverflow
Solution 1 - Rubyuser513951View Answer on Stackoverflow
Solution 2 - RubymegasView Answer on Stackoverflow
Solution 3 - RubyMichael KohlView Answer on Stackoverflow
Solution 4 - RubylukadView Answer on Stackoverflow
Solution 5 - Ruby3limin4t0rView Answer on Stackoverflow
Solution 6 - RubyVictor MorozView Answer on Stackoverflow
Solution 7 - RubyksolView Answer on Stackoverflow
Solution 8 - RubysawaView Answer on Stackoverflow
Solution 9 - RubytaniusView Answer on Stackoverflow
Solution 10 - RubyEugeneView Answer on Stackoverflow