Vérifier si une variable est définie?

Comment puis-je vérifier si une variable est définie dans Ruby? Existe-t-il une méthode de type isset ?

Utilisez le defined? mot clé ( documentation ). Il retournera une chaîne avec le type de l’élément, ou nil s’il n’existe pas.

 >> a = 1 => 1 >> defined? a => "local-variable" >> defined? b => nil >> defined? nil => "nil" >> defined? Ssortingng => "constant" >> defined? 1 => "expression" 

Comme le disait skalee: “Il est intéressant de noter que la variable qui est mise à zéro est initialisée.”

 >> n = nil >> defined? n => "local-variable" 

Ceci est utile si vous ne voulez rien faire s’il existe, mais créez-le s’il n’existe pas.

 def get_var @var ||= SomeClass.new() end 

Cela ne crée la nouvelle instance qu’une seule fois. Après cela, il ne fait que continuer à retourner le var.

La syntaxe correcte pour l’instruction ci-dessus est la suivante:

 if (defined?(var)).nil? # will now return true or false print "var is not defined\n".color(:red) else print "var is defined\n".color(:green) end 

substituer ( var ) par votre variable. Cette syntaxe renverra une valeur true / false pour évaluation dans l’instruction if.

defined?(your_var) fonctionnera. Selon ce que vous faites, vous pouvez également faire quelque chose comme your_var.nil?

Essayez “à moins que” au lieu de “si”

 a = "apple" # Note that b is not declared c = nil unless defined? a puts "a is not defined" end unless defined? b puts "b is not defined" end unless defined? c puts "c is not defined" end 

Utiliser defined? YourVariable defined? YourVariable
Restez simple, idiot ..;)

Tu peux essayer:

 unless defined?(var) #ruby code goes here end => true 

Parce qu’il retourne un booléen.

Voici du code, rien de sorcier mais ça marche assez bien

 require 'rubygems' require 'rainbow' if defined?(var).nil? # .nil? is optional but might make for clearer intent. print "var is not defined\n".color(:red) else print "car is defined\n".color(:green) end 

Clairement, le code de coloration n’est pas nécessaire, juste une belle visualisation dans cet exemple de jouet.

C’est la réponse clé: le défini? méthode. La réponse acceptée ci-dessus illustre parfaitement cela.

Mais il y a un requin qui se cache sous les vagues …

Considérons ce type de motif rbuy commun:

  def method1 @x ||= method2 end def method2 nil end 

Arrêtons-nous et réfléchissons à cela pendant une seconde. la méthode 2 renvoie toujours nil. La première fois que vous appelez method1, la variable @x n’est pas définie. Par conséquent, method2 sera exécuté. et la méthode 2 définira @x sur nil. C’est bien, et tout va bien. Mais que se passe-t-il la deuxième fois que vous appelez méthode1?

Rappelez-vous que @x a déjà été mis à zéro. Mais la méthode 2 sera encore exécutée? Si method2 est une entreprise coûteuse, ce n’est peut-être pas ce que vous voulez.

Laissez le défini? méthode à la rescousse

  def method1 return @x if defined? @x @x = method2 end 

Si vous ne connaissiez pas ce tour, alors “tu vas avoir besoin d’un plus gros bateau”.

Comme beaucoup d’autres exemples le montrent, vous n’avez pas besoin d’un booléen d’une méthode pour faire des choix logiques dans Ruby. Ce serait une mauvaise forme de tout contraindre à un booléen à moins que vous ayez réellement besoin d’un booléen.

Mais si vous avez absolument besoin d’un booléen. Utilisation !! (Bang Bang) ou “Falsy Falsy révèle la vérité”.

 › irb >> a = nil => nil >> defined?(a) => "local-variable" >> defined?(b) => nil >> !!defined?(a) => true >> !!defined?(b) => false 

Pourquoi ne pas payer pour contraindre:

 >> (!!defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red)) == (defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red)) => true 

Voici un exemple où il est important car il repose sur la coercition implicite de la valeur booléenne à sa représentation sous forme de chaîne.

 >> puts "var is defined? #{!!defined?(a)} vs #{defined?(a)}" var is defined? true vs local-variable => nil 

Veuillez noter la distinction entre “défini” et “assigné”.

 $ ruby -e 'def f; if 1>2; x=99; end;px, defined? x; end;f' nil "local-variable" 

x est défini même s’il n’est jamais atsortingbué!

Il convient de mentionner que l’utilisation defined pour vérifier si un champ spécifique est défini dans un hachage peut se comporter de manière inattendue:

 var = {} if defined? var['unknown'] puts 'this is unexpected' end # will output "this is unexpected" 

La syntaxe est correcte ici, mais defined? var['unknown'] defined? var['unknown'] sera évalué à la chaîne "method" , donc le bloc if sera exécuté

edit: La notation correcte pour vérifier si une clé existe dans un hachage serait:

 if var.key?('unknown') 

En outre, vous pouvez vérifier si elle est définie dans une chaîne par interpolation, si vous codez:

 puts "Is array1 defined and what type is it? #{defined?(@array1)}" 

Le système vous indiquera le type s’il est défini. S’il n’est pas défini, il renverra simplement un avertissement indiquant que la variable n’est pas initialisée.

J’espère que cela t’aides! 🙂

defined? est génial, mais si vous êtes dans un environnement Rails, vous pouvez également utiliser try , surtout si vous souhaitez vérifier un nom de variable dynamic:

 foo = 1 my_foo = "foo" my_bar = "bar" try(:foo) # => 1 try(:bar) # => nil try(my_foo) # => 1 try(my_bar) # => nil