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
  • Select an option

  • Save ChuckJHardySnippets/2000623 to your computer and use it in GitHub Desktop.

Select an option

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
@prodis

prodis commented Oct 30, 2014

Copy link
Copy Markdown

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

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

@flvrone

flvrone commented Aug 14, 2016

Copy link
Copy Markdown

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

@dbwest

dbwest commented Sep 23, 2016

Copy link
Copy Markdown

@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
Copy Markdown

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

perlun commented Jan 27, 2017

Copy link
Copy Markdown

(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