对于 not_nil,是否存在与 nil 相反的 Ruby 或 Ruby 主义?

我没有使用 Ruby 的经验,所以我的代码看起来“丑陋”而且不惯用:

def logged_in?
!user.nil?
end

我更喜欢

def logged_in?
user.not_nil?
end

但是找不到与 nil?相反的方法

71116 次浏览

Maybe this could be an approach:

class Object
def not_nil?
!nil?
end
end

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.

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

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

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.

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.

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. ;-)