2

Some valid ActiveRecord objects return false for present?:

object.nil? # => false
object.valid? # => true
object.present? # => false
object.blank? # => true

I prefer object.present? over not object.nil?. What determines the return value of present?/blank??

EDIT: Found the answer: I had redefined the empty? method on this class, not the blank? or present? method; along the lines of @Simone's answer, blank? is using empty? behind the scenes.

Sasgorilla
  • 2,403
  • 2
  • 29
  • 56
  • 1
    http://stackoverflow.com/questions/885414/a-concise-explanation-of-nil-v-empty-v-blank-in-ruby-on-rails – Léo Feb 15 '16 at 13:34
  • 1
    I prefer `object.present?` over `not object.nil?`--If you want something non-standard, then just define it by yourself and use it. If you don't want to do that, then don't prefer like that. – sawa Feb 15 '16 at 13:47
  • 1
    *"Some valid `ActiveRecord` objects return `false` for `present?`"* - really? Could you give an example? – Stefan Feb 15 '16 at 13:50

2 Answers2

7

present? is the opposite of blank?. blank? implementation depends on the type of object. Generally speaking, it returns true when the value is empty or like-empty.

You can get an idea looking at the tests for the method:

  BLANK = [ EmptyTrue.new, nil, false, '', '   ', "  \n\t  \r ", ' ', "\u00a0", [], {} ]
  NOT   = [ EmptyFalse.new, Object.new, true, 0, 1, 'a', [nil], { nil => 0 } ]

  def test_blank
    BLANK.each { |v| assert_equal true, v.blank?,  "#{v.inspect} should be blank" }
    NOT.each   { |v| assert_equal false, v.blank?, "#{v.inspect} should not be blank" }
  end

  def test_present
    BLANK.each { |v| assert_equal false, v.present?, "#{v.inspect} should not be present" }
    NOT.each   { |v| assert_equal true, v.present?,  "#{v.inspect} should be present" }
  end

An object can define its own interpretation of blank?. For example

class Foo
  def initialize(value)
    @value = value
  end
  def blank?
    @value != "foo"
  end
end

Foo.new("bar").blank?
# => true

Foo.new("foo").blank?
# => false

If not specified, it will fallback to the closest implementation (e.g. Object).

Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
  • Why `EmptyTrue` and `EmptyFalse` instead of the singleton TrueClass/FalseClass? – max Feb 15 '16 at 13:49
  • @max take a look at the test, these are test classes with a custom implementation of `empty?`. And regarding `TrueClass`/`FalseClass` - try to create an instance via `TrueClass.new` (won't work). – Stefan Feb 15 '16 at 13:52
  • I don't think you understood my question, why use a stand-in instead of `true` / `false`. It just seems weird to stub out the object under test. – max Feb 15 '16 at 14:09
1

From the documentation for Object#present?

An object is present if it's not blank.

In your case, object is blank, so present? will return false. Validity of the object does not really matter.

Stefan
  • 109,145
  • 14
  • 143
  • 218
eugen
  • 8,916
  • 11
  • 57
  • 65
  • So, the question is, why is my object blank? And I just figured it out: I redefined the `empty?` method and apparently it's using this. – Sasgorilla Feb 17 '16 at 00:37