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

66,111

Solution 1

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

Solution 2

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

Solution 3

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.

Solution 4

Maybe this could be an approach:

class Object
  def not_nil?
    !nil?
  end
end

Solution 5

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

Share:
66,111
berkes
Author by

berkes

Bèr Kessels is entrepeneur and owner of webdevelopment company berk.es. Open Source Webdelopment. Specialised in Ruby, Rails and Sinatra.

Updated on July 08, 2022

Comments

  • berkes
    berkes almost 2 years

    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?

  • berkes
    berkes over 13 years
    I added a tag to my original post, indicating that -indeed- I am using Rails, hence the user.present? is present. AFAIK that indeed is the exact opposite of nil? Hence exactly what I need (in this context, a rails project)
  • berkes
    berkes over 13 years
    Good idea. I make from this that there is no not_nil? in Ruby. But should this not be !self.nil? rather then !nil?, or is selfimplicit?
  • MarkD
    MarkD over 13 years
    You don't need self. It will be implied.
  • lambshaanxy
    lambshaanxy almost 13 years
    Beware: present? requires a non-blank string. ! "".nil? returns true, but "".present? returns false.
  • likethesky
    likethesky over 11 years
    Beware 2: I'll also note that !!user does NOT distinguish between user being nil and user being false; the double-bang usage conflates those two. So if you're truly wanting to determine if an object is not nil (meaning, it's: true, false, 0, "", anything other than nil), you need to use the 'ugly' approach that berkes doesn't like or the monkeypatch that @Tempus proposes below. Of course in this case where not nil is not needed (a user in Rails), the approach taken by Samo is the least ugly, imo.
  • Dudo
    Dudo about 10 years
    false.present? == false !false.nil? == true
  • tokland
    tokland over 7 years
    The expectation with a method ending with a ? is that it returns a boolean. !!value is the classic way to convert anything to a boolean. Not exactly the same, but in this case Object#present? in RoR is also good.
  • Ekkstein
    Ekkstein over 7 years
    This answer doesn't at all answer the question asked. It's an answer to this particular implementation problem.
  • justingordon
    justingordon almost 7 years
    this actually breaks in Ruby 2.4 with Path! [43] (pry) #<ReactOnRails::AssetsPrecompile>: 0> assets_path.blank? true [44] (pry) #<ReactOnRails::AssetsPrecompile>: 0> assets_path.to_s "/var/folders/rp/_k99k0pn0rsb4d3lm9l3dnjh0000gn/T/d20170603-‌​96466-zk7di7" [45] (pry) #<ReactOnRails::AssetsPrecompile>: 0> assets_path.present? false [46] (pry) #<ReactOnRails::AssetsPrecompile>: 0> assets_path.nil? false
  • A Fader Darkly
    A Fader Darkly almost 7 years
    Self is implied when reading from instance methods (or accessors, which are really just methods). When setting values, a variable local to the method will be created before Ruby checks the class instance for a setter method of the same name. General rule: if you have an attr_accessor called xxx, use "self.xxx = 3" (setting a value) or "temp = xxx" (reading the value). Using "xxx = 3" will not update the accessor, just create a new variable in the method scope.
  • Mike
    Mike over 6 years
    This answer is not correct. false.nil? is false, while false.present? is ALSO false!
  • berkes
    berkes about 5 years
    How is that different from my_hash.values_at("Name", "name").find?
  • Ian
    Ian about 5 years
    It's exactly the same. I had some other logic in my original map that I removed for simplicity in this example, so as-written here it's interchangeable with values_at. The important part is what gets passed to find.
  • Yason
    Yason over 4 years
    Should be included in the accepted answer. false.blank? is not same as as false.nil?
  • Abhinav Kaushal Keshari
    Abhinav Kaushal Keshari over 3 years
    present? will query your database, nil? will not, be careful with that