Ruby: Comment convertir une chaîne en booléen

J’ai une valeur qui sera l’une des quatre choses: booléen vrai, booléen faux, la chaîne “true”, ou la chaîne “false”. Je veux convertir la chaîne en booléen si c’est une chaîne, sinon laissez-la non modifiée. En d’autres termes:

“vrai” devrait devenir vrai

“false” devrait devenir faux

vrai devrait restr vrai

false devrait restr faux

 def true?(obj) obj.to_s == "true" end 

Si vous utilisez Rails 5, vous pouvez faire ActiveModel::Type::Boolean.new.cast(value) .

Dans Rails 4.2, utilisez ActiveRecord::Type::Boolean.new.type_cast_from_user(value) .

Le comportement est légèrement différent, comme dans Rails 4.2, la valeur vraie et les valeurs fausses sont vérifiées. Dans Rails 5, seules les valeurs fausses sont vérifiées – sauf si les valeurs sont nulles ou correspondent à une valeur fausse, elles sont supposées être vraies. Les valeurs fausses sont les mêmes dans les deux versions: FALSE_VALUES = [false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"]

Rails 5 Source: https://github.com/rails/rails/blob/5-1-stable/activemodel/lib/active_model/type/boolean.rb

 h = { "true"=>true, true=>true, "false"=>false, false=>false } ["true", true, "false", false].map { |e| h[e] } #=> [true, true, false, false] 
 if value.to_s == 'true' true elsif value.to_s == 'false' false end 

J’ai souvent utilisé ce modèle pour étendre le comportement de base de Ruby afin de faciliter la conversion de types de données arbitraires en valeurs booléennes, ce qui facilite la gestion des parameters d’URL, etc.

 class Ssortingng 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 

Alors disons que vous avez un paramètre foo qui peut être:

  • un entier (0 est faux, tous les autres sont vrais)
  • un vrai booléen (vrai / faux)
  • une chaîne (“true”, “false”, “0”, “1”, “TRUE”, “FALSE”)
  • néant

Au lieu d’utiliser un tas de conditions, vous pouvez simplement appeler foo.to_boolean et cela fera le rest de la magie pour vous.

Dans Rails, j’ajoute ceci à un initialiseur nommé core_ext.rb dans presque tous mes projets, car ce modèle est si courant.

 ## 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 

Ne pense pas trop:

 bool_or_ssortingng.to_s == "true" 

Alors,

 "true".to_s == "true" #true "false".to_s == "true" #false true.to_s == "true" #true false.to_s == "true" #false 

Vous pouvez également append “.downcase” si vous êtes préoccupé par les majuscules.

Bien que j’aime l’approche de hachage (je l’ai utilisée dans le passé pour des trucs similaires), étant donné que vous ne vous souciez que de faire correspondre des valeurs de vérité – puisque tout le rest est faux – vous pouvez vérifier l’inclusion dans un tableau:

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

ou si d’autres valeurs pouvaient être considérées comme véridiques:

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

vous devrez faire d’autres choses si votre value origine peut être mixte:

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

mais encore une fois, pour votre description spécifique de votre problème, vous pourriez vous en sortir avec ce dernier exemple comme solution.

Un bijou comme https://rubygems.org/gems/to_bool peut être utilisé, mais il peut facilement être écrit sur une seule ligne en utilisant une expression régulière ou ternaire.

exemple regex:

 boolean = (var.to_s =~ /^true$/i) == 0 

exemple ternaire:

 boolean = var.to_s.eql?('true') ? true : false 

L’avantage de la méthode regex est que les expressions régulières sont flexibles et peuvent correspondre à une grande variété de modèles. Par exemple, si vous pensez que var peut être “True”, “False”, “T”, “F”, “t” ou “f”, vous pouvez modifier l’expression rationnelle:

 boolean = (var.to_s =~ /^[Tt].*$/i) == 0 

Dans les rails, j’ai déjà fait quelque chose comme ceci:

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

Ce qui est bien si vous essayez de faire correspondre vos comparaisons de chaînes booléennes de la même manière que les rails pour votre firebase database.

Qu’en est-il du smthing comme:

 boolean_str = 'false' boolean = eval(boolean_str)