【问题标题】:What determines the return value of `present?`?是什么决定了`present?`的返回值?
【发布时间】:2016-05-26 10:33:35
【问题描述】:

一些有效的ActiveRecord 对象为present? 返回false

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

比起not object.nil?,我更喜欢object.present?。什么决定了present?/blank?的返回值?

编辑:找到答案:我在这个类上重新定义了empty? 方法,而不是blank?present? 方法;根据@Simone 的回答,blank? 在幕后使用empty?

【问题讨论】:

  • 我更喜欢object.present? 而不是not object.nil?--如果你想要一些非标准的东西,那就自己定义并使用它。如果你不想那样做,那就不要那样做。
  • “一些有效的ActiveRecord 对象为false 返回present? - 真的吗?你能举个例子吗?

标签: ruby-on-rails ruby


【解决方案1】:

来自Object#present?的文档

如果对象不为空,则存在对象。

在你的情况下,对象是空白的,所以present? 将返回false。对象的有效性并不重要。

【讨论】:

  • 那么,问题是,为什么我的对象是空白的?我刚刚想通了:我重新定义了empty? 方法,显然它正在使用它。
【解决方案2】:

present?blank? 相反。 blank? 的实现取决于对象的类型。一般来说,当值为空或like-empty时返回true。

你可以得到一个想法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

对象可以定义自己对blank? 的解释。例如

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

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

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

如果未指定,它将回退到最接近的实现(例如Object)。

【讨论】:

  • 为什么用EmptyTrueEmptyFalse 而不是单例TrueClass/FalseClass?
  • @max 看看测试,这些是自定义实现empty? 的测试类。关于TrueClass/FalseClass - 尝试通过TrueClass.new 创建一个实例(不起作用)。
  • 我认为你没有理解我的问题,为什么要使用替身而不是 true / false。将被测对象存根似乎很奇怪。
猜你喜欢
  • 1970-01-01
  • 2022-01-22
  • 2021-07-19
  • 1970-01-01
  • 2021-12-15
  • 2016-02-15
  • 2013-04-09
  • 2012-02-10
  • 2019-04-14
相关资源
最近更新 更多