In Ruby, the numeric 0
is a truthy value, meaning it is converted to true
when evaluated in a boolean expression. This is unlike languages such as JavaScript and Python, where the numeric 0
is falsy (ie. evaluates as false
in a boolean expression). This is also a departure from the underlying hardware that our programs run on, where a 1
bit represents true
and a 0
bit represents false
. We can check that 0
is truthy in an irb
console by using a double bang to to convert 0
to its boolean value:
~ irb
3.0.2 :001 > !!0
=> true
In Ruby, nil
and false
are the only falsy values, which is an elegant part of the language’s design. This philosophy of 0
as truthy is seen in some of ActiveSupport’s widely-used methods:
3.0.2 :001 > 0.present?
=> true
3.0.2 :002 > 0.blank?
=> false
0.present?
returns true
because it is not blank. 0
is not blank because it is not logically false, and not considered to be “empty” the way " "
, { }
, and []
are.
However, did you know that this philosophy of “0
as truthy” doesn’t extend to all methods provided by ActiveRecord and ActiveSupport?
For each attribute on an ActiveRecord object, ActiveRecord generates a “query method” that ends with a ?
character. This method checks for the presence of that attribute. For example, if we have a model named Person
with an attribute called age
, ActiveRecord generates a method named age?
that behaves like so:
p = Person.new
p.age = nil
p.age? # returns false
p.age = 18
p.age? # returns true
How does .age?
behave when age
is set to 0
?
p.age = 0
p.age? # returns false
This behaviour (0
returning false
when being read in a query method) is well-documented in the ActiveRecord::Base
documentation, and its source code in the ActiveRecord
codebase is easy to follow. In some cases, this can result in more readable code – for example, if we have a BankAccount
model with a balance
attribute, we could check if it has a non-zero balance by calling the .balance?
method. However, it’s a departure from the “0
as truthy” design philosophy, and so it’s an interesting edge case to consider in the Rails ecosystem!
Start your journey towards writing better software, and watch this space for new content.