# Why does false.blank? == true?

**URL:** <https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681>\
**Category:** rubyonrails-talk\
**Tags:** activesupport\
**Created:** [November 1, 2022, 5:17pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681 "2022-11-01T17:17:03Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Delon\_Newman](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/delon_newman/32/12973_2.png) [@Delon\_Newman](https://discuss.rubyonrails.org/u/Delon_Newman)\
**Post date:** [November 1, 2022, 5:17pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/1 "2022-11-01T17:17:03Z")

</div>

I’m quite sure `blank?` and friends are universally loved. But, just recently I’ve learned through an annoying bug 😅 that `false.blank? == true`. This seems unexpected. Can anyone help me to understand the rationale for that?

---

<div class="post-metadata">

**Author:** ![rafaelcamargo](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/rafaelcamargo/32/5182_2.png) [@rafaelcamargo](https://discuss.rubyonrails.org/u/rafaelcamargo)\
**Post date:** [November 1, 2022, 7:18pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/2 "2022-11-01T19:18:09Z")

</div>

The great question is: why is there a method that verifies if a value is blank, if that value could never, by definition, be blank? 😆

Accordingly to the 7.0.4 docs: [“An instance of ActiveSupport::TimeWithZone is never blank”](https://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html#method-i-blank-3F:~:text=Link-,An%20instance%20of%20ActiveSupport%3A%3ATimeWithZone%20is%20never%20blank,-Source%3A%20show)

Of course that `blank?` has at least another 3 different implementations in other classes, but in this case doesn’t make sense to me either.

I’ll keep digging into docs and implementation trying to answer that, but it oddingly seems a bug. Nice observation!

---

<div class="post-metadata">

**Author:** ![e\_a](https://avatars.discourse-cdn.com/v4/letter/e/9fc348/32.png) [@e\_a](https://discuss.rubyonrails.org/u/e_a)\
**Post date:** [November 1, 2022, 10:18pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/3 "2022-11-01T22:18:35Z")

</div>

`false.blank? == true` seems correct for me.

In Ruby only `false` and `nil` evaluate `false` in a conditional. Everything else evaluates to `true`. These semantics are simple but sometimes you want different semantics. You want things like an empty string or an empty array to evaluate to false. Therefore as an extension Rails adds the concept of “blank” to includes other things. But the `false` and `nil` are also considered blank. The new items added are in addition to what is already considered `false`. Some languages/libraries uses the term “falsey” as this sort of extended version of false.

| value | Ruby | Rails |
| --- | --- | --- |
| nil | false | blank |
| false | false | blank |
| `[]` | true | blank |
| `''` | true | blank |

NOTE: There are other things that can evaluate to blank besides just `[]` and `''`. Really anything that responds to `empty?` is `blank?`. I just used `[]` and `''` as to common examples of things that are blank.

---

<div class="post-metadata">

**Author:** ![kiddrew](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/kiddrew/32/9538_2.png) [@kiddrew](https://discuss.rubyonrails.org/u/kiddrew)\
**Post date:** [March 22, 2023, 7:27pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/4 "2023-03-22T19:27:36Z")

</div>

I disagree with this. The word “blank” to me means “has no value”. Boolean has 3 possible states - true, false, and nil. Nil is the absence of value, so it’s blank. True and false are both values, so neither are blank.

This confusion has caused a number of logic issues for me in Rails.

---

<div class="post-metadata">

**Author:** ![wale](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/wale/32/13729_2.png) [@wale](https://discuss.rubyonrails.org/u/wale)\
**Post date:** [March 23, 2023, 12:03pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/5 "2023-03-23T12:03:29Z")

</div>

The docs define the meaning of blank.

[https://apidock.com/rails/Object/blank%3F](https://apidock.com/rails/Object/blank%3F)

While the word may mean different things to each of us, the “correct” meaning is what’s defined in the docs.

---

<div class="post-metadata">

**Author:** ![joeldrapper](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/joeldrapper/32/5138_2.png) [@joeldrapper](https://discuss.rubyonrails.org/u/joeldrapper)\
**Post date:** [March 23, 2023, 2:32pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/6 "2023-03-23T14:32:57Z")

</div>

I agree this is bit confusing. If you’re testing a boolean, you could use `nil?` to get the result you’re after.

---

<div class="post-metadata">

**Author:** ![kiddrew](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/kiddrew/32/9538_2.png) [@kiddrew](https://discuss.rubyonrails.org/u/kiddrew)\
**Post date:** [March 23, 2023, 4:50pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/7 "2023-03-23T16:50:44Z")

</div>

@wale Yeah, I’m not debating how it’s implemented. My point is that I think how it’s implemented is not intuitive.

---

<div class="post-metadata">

**Author:** ![fxn](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/fxn/32/12956_2.png) [@fxn](https://discuss.rubyonrails.org/u/fxn)\
**Post date:** [March 24, 2023, 9:52am UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/8 "2023-03-24T09:52:09Z")

</div>

In Ruby there is no Boolean type. The boolean space is flat, with `false` and `nil` being false, and everything else being true.

The boolean semantics of a Ruby object do not matter for `blank?`, as you can see by the amount of objects that are true and blank.

In the case of the singletons, `false` is considered to be blank and `true` is not. And this definition makes sense to me. You need to revise the definition of blank in your head to match what it truly means (which is not absence of value).

That said, I believe people tend to overuse `blank?`, I prefer `empty?` or `nil?` or just evaluate the object in boolean context where that is enough.

---

<div class="post-metadata">

**Author:** ![kiddrew](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/kiddrew/32/9538_2.png) [@kiddrew](https://discuss.rubyonrails.org/u/kiddrew)\
**Post date:** [March 24, 2023, 1:05pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/9 "2023-03-24T13:05:09Z")

</div>

I realize this is semantics and one person’s subjective interpretation of what words mean. It also doesn’t matter one bit what I think because there’s no way this is going to change at this point.

To me, the implementations of `blank?` and `present?` are both incorrect for a boolean false. The method `present?` means “has value” in the context of a string, so why doesn’t it in the context of a boolean? The same argument for `blank?` - it means “has no value” for a string but not for a boolean. That feels inconsistent.

For evidence to back up my case (and then I’ll give it a rest), you can’t validate the presence of a boolean. Instead you have to validate inclusion in `[true,false]` and that just feels wrong. If there weren’t a presence validation that behaves incorrectly (IMO), I wouldn’t care at all.

---

<div class="post-metadata">

**Author:** ![walterdavis](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/walterdavis/32/705_2.png) [@walterdavis](https://discuss.rubyonrails.org/u/walterdavis)\
**Post date:** [March 24, 2023, 3:37pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/10 "2023-03-24T15:37:53Z")

</div>

I know what you’re saying, and from “a certain point of view”, you are absolutely correct. I used to believe that a boolean could only have two states, but a co-worker convinced me otherwise. It all depends on what you want that field to represent.

For many things, I often will use the database default to enforce that if it isn’t true, it is FALSE, and therefore never NIL. Example might be a `published` boolean.

But that’s not the same thing as I might need for an `approved` boolean. In that case, there are really three possible states: yes, no, and ‘haven’t decided’. A true (nullable) boolean can represent all of them. Perhaps that would be better modeled by an enum, with named states for the three possibilities, but that’s the example that opened my eyes.

Maybe we make it sweeter, and add a `validates :my_field, boolean: true` to the framework. But would that be another bikeshed to paint?

Walter

---

<div class="post-metadata">

**Author:** ![kiddrew](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/kiddrew/32/9538_2.png) [@kiddrew](https://discuss.rubyonrails.org/u/kiddrew)\
**Post date:** [March 24, 2023, 4:58pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/11 "2023-03-24T16:58:27Z")

</div>

Yes, exactly. You described my two scenarios perfectly. Sometimes I want to validate that the user explicitly answered a true/false question, and in that case the absence of true is not false, it’s nil, and assuming false is incorrect.

As I said, there’s a workaround for this so it’s a minor annoyance. The fact that we’re even debating such a small issue must mean that Rails is pretty great. 🙂

---

<div class="post-metadata">

**Author:** ![joeldrapper](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/joeldrapper/32/5138_2.png) [@joeldrapper](https://discuss.rubyonrails.org/u/joeldrapper)\
**Post date:** [March 25, 2023, 6:00am UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/12 "2023-03-25T06:00:45Z")

</div>

If you know it’s going to be one of `nil`, `false`, `true`, you _can_ validate the presence of a boolean with the `nil?` predicate.

---

<div class="post-metadata">

**Author:** ![kiddrew](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/kiddrew/32/9538_2.png) [@kiddrew](https://discuss.rubyonrails.org/u/kiddrew)\
**Post date:** [March 25, 2023, 6:05pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/13 "2023-03-25T18:05:20Z")

</div>

@joeldrapper Trying to understand what you mean. Can you give me an example?

---

<div class="post-metadata">

**Author:** ![joeldrapper](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/joeldrapper/32/5138_2.png) [@joeldrapper](https://discuss.rubyonrails.org/u/joeldrapper)\
**Post date:** [March 26, 2023, 7:57am UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/14 "2023-03-26T07:57:46Z")

</div>

@kiddrew sorry, I mean if you have a value that you know is a nullable boolean (`nil`, `false` or `true`), then you can check if it “has a value” with the `nil?` predicate.

```ruby
true.nil? # → false
false.nil? # → false
nil.nil? # → true

```

---

<div class="post-metadata">

**Author:** ![kiddrew](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/kiddrew/32/9538_2.png) [@kiddrew](https://discuss.rubyonrails.org/u/kiddrew)\
**Post date:** [March 26, 2023, 3:49pm UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/15 "2023-03-26T15:49:41Z")

</div>

@joeldrapper Aha, yeah I can write a custom validator. I just meant that you can’t use the built-in PresenceValidator for a boolean. As I said, it’s a minor annoyance.

---

<div class="post-metadata">

**Author:** ![pavlik](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/pavlik/32/9554_2.png) [@pavlik](https://discuss.rubyonrails.org/u/pavlik)\
**Post date:** [April 27, 2023, 8:22am UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/16 "2023-04-27T08:22:11Z")

</div>

I might be wrong here, but only `nil` has no value in Ruby, so we already have a method answering that `nil?`

---

<div class="post-metadata">

**Author:** ![Delon\_Newman](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/delon_newman/32/12973_2.png) [@Delon\_Newman](https://discuss.rubyonrails.org/u/Delon_Newman)\
**Post date:** [June 1, 2023, 8:35am UTC](https://discuss.rubyonrails.org/t/why-does-false-blank-true/81681/17 "2023-06-01T08:35:38Z")

</div>

> [@fxn](#):
>
> That said, I believe people tend to overuse `blank?`, I prefer `empty?` or `nil?` or just evaluate the object in boolean context where that is enough.

I find myself doing the same. It’s nice to see someone else feels the same 😅.
