Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Ruby: Convert String to Boolean
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

prodis commented Oct 30, 2014

I have just made the wannabe_bool gem to convert strings, integers, symbols and nil values to boolean, using a #to_b method.
https://github.com/prodis/wannabe_bool

'true'.to_b # => true
1.to_b      # => true
:true.to_b  # => true

'false'.to_b # => false
0.to_b       # => false
:false.to_b  # => false
nil.to_b     # => false

# and more
  module StringExtension
    extend ActiveSupport::Concern
    def to_bool
      result = false
      result = (!self.nil? && !(self.downcase.squish == 'false') && (self.downcase.squish == 'true' || self != '0' || self == '1'))

      result
    end
  end

so after defining my module, I just include it. And I don't want that to effect system wide.

 String.class_eval do
    include StringExtension
  end

Examples:

[13] pry(#<ProductFinder>)> >> "1".to_bool 
=> true
[14] pry(#<ProductFinder>)> 
[15] pry(#<ProductFinder>)> >> "0".to_bool 
=> false
[16] pry(#<ProductFinder>)> 
[17] pry(#<ProductFinder>)> >> "sdfj".to_bool 
=> true
[18] pry(#<ProductFinder>)> 
[19] pry(#<ProductFinder>)> >> "true".to_bool 
=> true
[20] pry(#<ProductFinder>)> 
[21] pry(#<ProductFinder>)> >> "false".to_bool
=> false

blank? throws a NoMethodError in Ruby 2.2.1, I think because blank? is now replaced with empty?

@pacharanero, #blank? is Ruby on Rails method only.

dbwest commented Sep 23, 2016

@rubyrider: can't to_bool be written more simply?

def to_bool
    (!self.nil? && !(self.downcase.squish == 'false') && (self.downcase.squish == 'true' || self != '0' || self == '1'))
end

Also, I still don't understand how the approach doesn't effect things 'system wide'

Aren't you still monkeypatching String?

You are using class_eval which is more flexible than

class Foo
#monkeypatch here
end

but it still looks like a system wide monkeypatch to me.

please correct me if I'm wrong, I'd like to know more.

http://stackoverflow.com/questions/9399358/monkey-patching-vs-class-eval

Am I missing something? What is extend ActiveSupport::Concern doing here?

My approach to avoid affect whole system:

# This module add refinements to cast string to boolean
module StringToBooleanRefinements
    refine String do
      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
end

Class that will uses this refinement

class RefinedStringClass
  using StringToBooleanRefinements

   def string_true
       'true'.to_bool   
   end
   def string_false
      'false'.to_bool
   end
end

perlun commented Jan 27, 2017

(For reference, Ruby refinements was introduced in Ruby 2.0. So if you are stuck on some antique version, it will not work.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment