Drawing a Blank
by Mike Fulcher

Ruby boolean type casting
Monday, June 17, 2013

It’s been a pet peeve of mine for a while that Ruby doesn’t provide much support for typecasting boolean values. Many other programming languages implement boolean typecasting (for example in javascript 0 == false and 1 == true). In Ruby you can use the !! (“bang bang”) technique to force a boolean value, but this is a more primitive method that doesn’t account for very much beyond nil representing a false value – everything else will return true.

!!1 # => true
!!0 # => true

Implementing boolean typecasting

I’ve started dropping this into almost all of my Ruby projects:

class String
  def to_bool
    return true if self == true || self =~ (/^(true|t|yes|y|1)$/i)
    return false if self == false || self.blank? || self =~ (/^(false|f|no|n|0)$/i)
    raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
  end
end

class Fixnum
  def to_bool
    return true if self == 1
    return false if self == 0
    raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
  end
end

class TrueClass
  def to_i; 1; end
  def to_bool; self; end
end

class FalseClass
  def to_i; 0; end
  def to_bool; self; end
end

class NilClass
  def to_bool; false; end
end

In Rails, this can be popped into a new file in config/initializers. Now you can do boolean typecasting on string, number, boolean, and nil values:

# Numbers...
1.to_bool # => true
0.to_bool # => false

# Numbers as strings...
'1'.to_bool # => true
'0'.to_bool # => false

# Truthy strings (case insensitive)...
'true'.to_bool  # => true  (alias: 't')
'false'.to_bool # => false (alias: 'f')
'yes'.to_bool   # => false (alias: 'y')
'no'.to_bool    # => false (alias: 'n')

# Booleans...
true.to_bool  # => true
false.to_bool # => false

# Nil...
nil.to_bool # => false