berkes
berkes

Reputation: 27563

Is there a Ruby, or Ruby-ism for not_nil? opposite of nil? method?

I am not experienced in Ruby, so my code feels "ugly" and not idiomatic:

def logged_in?
  !user.nil?
end

I'd rather have something like

def logged_in?
  user.not_nil?
end

But cannot find such a method that opposites nil?

Upvotes: 102

Views: 78654

Answers (7)

Christopher Oezbek
Christopher Oezbek

Reputation: 26373

May I offer the Ruby-esque ! method on the result from the nil? method.

def logged_in?
  user.nil?.!
end

So esoteric that RubyMine IDE will flag it as an error. ;-)

Upvotes: 17

Ian
Ian

Reputation: 11810

I arrived at this question looking for an object method, so that I could use the Symbol#to_proc shorthand instead of a block; I find arr.find(&:not_nil?) somewhat more readable than arr.find { |e| !e.nil? }.

The method I found is Object#itself. In my usage, I wanted to find the value in a hash for the key name, where in some cases that key was accidentally capitalized as Name. That one-liner is as follows:

# Extract values for several possible keys 
#   and find the first non-nil one
["Name", "name"].map { |k| my_hash[k] }.find(&:itself)

As noted in other answers, this will fail spectacularly in cases where you are testing a boolean.

Upvotes: 2

A Fader Darkly
A Fader Darkly

Reputation: 3636

Beware other answers presenting present? as an answer to your question.

present? is the opposite of blank? in rails.

present? checks if there is a meaningful value. These things can fail a present? check:

"".present? # false
"    ".present? # false
[].present? # false
false.present? # false
YourActiveRecordModel.where("false = true").present? # false

Whereas a !nil? check gives:

!"".nil? # true
!"    ".nil? # true
![].nil? # true
!false.nil? # true
!YourActiveRecordModel.where("false = true").nil? # true

nil? checks if an object is actually nil. Anything else: an empty string, 0, false, whatever, is not nil.

present? is very useful, but definitely not the opposite of nil?. Confusing the two can lead to unexpected errors.

For your use case present? will work, but it's always wise to be aware of the difference.

Upvotes: 37

lwe
lwe

Reputation: 2625

when you're using ActiveSupport, there's user.present? http://api.rubyonrails.org/classes/Object.html#method-i-present%3F, to check just for non-nil, why not use

def logged_in?
  user # or !!user if you really want boolean's
end

Upvotes: 49

Samo
Samo

Reputation: 8240

You seem overly concerned with booleans.

def logged_in?
  user
end

If the user is nil, then logged_in? will return a "falsey" value. Otherwise, it will return an object. In Ruby we don't need to return true or false, since we have "truthy" and "falsey" values like in JavaScript.

Update

If you're using Rails, you can make this read more nicely by using the present? method:

def logged_in?
  user.present?
end

Upvotes: 52

Bitterzoet
Bitterzoet

Reputation: 2792

You can just use the following:

if object
  p "object exists"
else
  p "object does not exist"
end

This does not only work for nil but also false etc, so you should test to see if it works out in your usecase.

Upvotes: 4

Geo
Geo

Reputation: 96837

Maybe this could be an approach:

class Object
  def not_nil?
    !nil?
  end
end

Upvotes: 21

Related Questions