【Ruby on Rails】false.present? は true か false か

Ruby on Rails

結論は false です。

false.present?
=> false

ただ present? は存在をチェックするメソッドという認識があり、てっきりこのケースでも値ありとして true が返るものだとばかり思い込んでいました。
どういう挙動なのかが気になったので、少し調べてみることにします。

実際のソースコード

present?ActiveSupport で実装されています。
rails/activesupport/lib/active_support/core_ext/object/blank.rb at 7-1-stable · rails/rails

そこでは Object クラスに以下の通り blank? , present? を追加しています。

class Object
  # An object is blank if it's false, empty, or a whitespace string.
  # For example, +nil+, '', '   ', [], {}, and +false+ are all blank.
  #
  # This simplifies
  #
  #   !address || address.empty?
  #
  # to
  #
  #   address.blank?
  #
  # @return [true, false]
  def blank?
    respond_to?(:empty?) ? !!empty? : !self
  end

  # An object is present if it's not blank.
  #
  # @return [true, false]
  def present?
    !blank?
  end

  ...

present? 自体は blank? を単に論理否定したものとして定義されています。

また、blank? の実装は empty? が応答すれば empty? の値を取り、しないのであれば自身の論理否定した値を返すようになっています。
true, falseで考えると、empty? には応答できないので、自身の論理否定を返すような挙動になりそうです。

ただこれは Object クラスにて追加されたメソッドであり、True, False クラスでの定義も以下の通り実装され、オーバーライドされてました。

class FalseClass
  # +false+ is blank:
  #
  #   false.blank? # => true
  #
  # @return [true]
  def blank?
    true
  end
end

class TrueClass
  # +true+ is not blank:
  #
  #   true.blank? # => false
  #
  # @return [false]
  def blank?
    false
  end
end

つまりこれは、false は blank なものとして意味付けされているということです。
ドキュメントにも確かにその通り書かれています。
https://railsguides.jp/active_support_core_extensions.html#blank-questionmarkとpresent-questionmark

そういうものとして認識していくしかないですね。

ちなみに

  • 私のような false.blank? は true では?という考えの方は他にもいるようで、以下のコミュニティでも議論がなされてました。(同じように考える方はいるんだなぁ)
    Why does false.blank? == true? – rubyonrails-talk – Ruby on Rails Discussions
  • モデルで bool 値のカラムの必須チェックがしたい時、validates :hoge, presence: true ではなく、validates_inclusion_of :hoge, in: [true, false] のようにする必要があります。
    • 必須チェックは内部的に blank? が使われていることから、false だと blank? が true となってバリデーションエラーとなるためです。

参考

rails/activesupport/lib/active_support/core_ext/object/blank.rb at 7-1-stable · rails/rails Active Support コア拡張機能 – Railsガイド

タイトルとURLをコピーしました