Ruby: How to convert a string to boolean

前端 未结 14 795
抹茶落季
抹茶落季 2020-12-08 13:16

I have a value that will be one of four things: boolean true, boolean false, the string \"true\", or the string \"false\". I want to convert the string to a boolean if it i

相关标签:
14条回答
  • 2020-12-08 13:34

    In Rails I prefer using ActiveModel::Type::Boolean.new.cast(value) as mentioned in other answers here

    But when I write plain Ruby lib. then I use a hack where JSON.parse (standard Ruby library) will convert string "true" to true and "false" to false. E.g.:

    require 'json'
    azure_cli_response = `az group exists --name derrentest`  # => "true\n"
    JSON.parse(azure_cli_response) # => true
    
    azure_cli_response = `az group exists --name derrentesttt`  # => "false\n"
    JSON.parse(azure_cli_response) # => false
    

    Example from live application:

    require 'json'
    if JSON.parse(`az group exists --name derrentest`)
      `az group create --name derrentest --location uksouth`
    end
    

    confirmed under Ruby 2.5.1

    0 讨论(0)
  • 2020-12-08 13:35

    I've frequently used this pattern to extend the core behavior of Ruby to make it easier to deal with converting arbitrary data types to boolean values, which makes it really easy to deal with varying URL parameters, etc.

    class String
      def to_boolean
        ActiveRecord::Type::Boolean.new.cast(self)
      end
    end
    
    class NilClass
      def to_boolean
        false
      end
    end
    
    class TrueClass
      def to_boolean
        true
      end
    
      def to_i
        1
      end
    end
    
    class FalseClass
      def to_boolean
        false
      end
    
      def to_i
        0
      end
    end
    
    class Integer
      def to_boolean
        to_s.to_boolean
      end
    end
    

    So let's say you have a parameter foo which can be:

    • an integer (0 is false, all others are true)
    • a true boolean (true/false)
    • a string ("true", "false", "0", "1", "TRUE", "FALSE")
    • nil

    Instead of using a bunch of conditionals, you can just call foo.to_boolean and it will do the rest of the magic for you.

    In Rails, I add this to an initializer named core_ext.rb in nearly all of my projects since this pattern is so common.

    ## EXAMPLES
    
    nil.to_boolean     == false
    true.to_boolean    == true
    false.to_boolean   == false
    0.to_boolean       == false
    1.to_boolean       == true
    99.to_boolean      == true
    "true".to_boolean  == true
    "foo".to_boolean   == true
    "false".to_boolean == false
    "TRUE".to_boolean  == true
    "FALSE".to_boolean == false
    "0".to_boolean     == false
    "1".to_boolean     == true
    true.to_i          == 1
    false.to_i         == 0
    
    0 讨论(0)
  • 2020-12-08 13:35

    Although I like the hash approach (I've used it in the past for similar stuff), given that you only really care about matching truthy values - since - everything else is false - you can check for inclusion in an array:

    value = [true, 'true'].include?(value)
    

    or if other values could be deemed truthy:

    value = [1, true, '1', 'true'].include?(value)
    

    you'd have to do other stuff if your original value might be mixed case:

    value = value.to_s.downcase == 'true'
    

    but again, for your specific description of your problem, you could get away with that last example as your solution.

    0 讨论(0)
  • 2020-12-08 13:36

    Working in Rails 5

    ActiveModel::Type::Boolean.new.cast('t')     # => true
    ActiveModel::Type::Boolean.new.cast('true')  # => true
    ActiveModel::Type::Boolean.new.cast(true)    # => true
    ActiveModel::Type::Boolean.new.cast('1')     # => true
    ActiveModel::Type::Boolean.new.cast('f')     # => false
    ActiveModel::Type::Boolean.new.cast('0')     # => false
    ActiveModel::Type::Boolean.new.cast('false') # => false
    ActiveModel::Type::Boolean.new.cast(false)   # => false
    ActiveModel::Type::Boolean.new.cast(nil)     # => nil
    
    0 讨论(0)
  • 2020-12-08 13:38

    In rails, I've previously done something like this:

    class ApplicationController < ActionController::Base
      # ...
    
      private def bool_from(value)
        !!ActiveRecord::Type::Boolean.new.type_cast_from_database(value)
      end
      helper_method :bool_from
    
      # ...
    end
    

    Which is nice if you're trying to match your boolean strings comparisons in the same manner as rails would for your database.

    0 讨论(0)
  • 2020-12-08 13:40
    def true?(obj)
      obj.to_s.downcase == "true"
    end
    
    0 讨论(0)
提交回复
热议问题