Skip to content

Instantly share code, notes, and snippets.

@ChuckJHardySnippets
Forked from erskingardner/string_ext.rb
Created March 8, 2012 11:40
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save ChuckJHardySnippets/2000623 to your computer and use it in GitHub Desktop.
Save ChuckJHardySnippets/2000623 to your computer and use it in GitHub Desktop.
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
@ChuckJHardySnippets
Copy link
Author

@prodis
Copy link

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

@rubyrider
Copy link

  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

@pacharanero
Copy link

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

@FunkyloverOne
Copy link

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

@dbwest
Copy link

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?

@niltonvasques
Copy link

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
Copy link

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