Comment puis-je vérifier si une variable est définie dans Ruby? Existe-t-il une méthode de type isset
- disponible?
Utilisez le mot clé defined?
( documentation ). Il renverra une chaîne avec le type d’élément, ou nil
s’il n’existe pas.
>> a = 1
=> 1
>> defined? a
=> "local-variable"
>> defined? b
=> nil
>> defined? nil
=> "nil"
>> defined? String
=> "constant"
>> defined? 1
=> "expression"
Comme Skalee a commenté: "Il est à noter que la variable définie sur nil est initialisée."
>> n = nil
>> defined? n
=> "local-variable"
Ceci est utile si vous ne voulez rien faire s'il existe mais le créer s'il n'existe pas.
def get_var
@var ||= SomeClass.new()
end
Cela crée la nouvelle instance une seule fois. Après cela, il ne cesse de renvoyer 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
en remplaçant (var
) par votre variable. Cette syntaxe renverra une valeur true/false pour évaluation dans l'instruction if.
defined?(your_var)
fonctionnera. En fonction de ce que vous faites, vous pouvez également faire quelque chose comme your_var.nil?
Essayez "sauf" 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
Utilisez defined? YourVariable
Soyons simples, bête..;)
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, mais une belle représentation dans cet exemple de jouet.
C'est la réponse clé: la méthode defined?
. La réponse acceptée ci-dessus l'illustre parfaitement.
Mais il y a un requin qui se cache sous les vagues ...
Considérez ce type de motif Ruby commun:
def method1
@x ||= method2
end
def method2
nil
end
method2
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 method2
définissent @x
à nil
. C'est bien, et tout va bien. Mais que se passe-t-il la deuxième fois que vous appelez method1
?
Rappelez-vous que @x a déjà été défini sur nil. But method2
sera toujours exécuté à nouveau !! Si method2 est une entreprise coûteuse, cela pourrait ne pas être quelque chose que vous souhaitiez.
Laissez la méthode defined?
venir à la rescousse - avec cette solution, ce cas particulier est traité - utilisez les éléments suivants:
def method1
return @x if defined? @x
@x = method2
end
Le diable est dans les détails: mais vous pouvez échapper à ce requin caché avec la méthode defined?
.
Tu peux essayer:
unless defined?(var)
#Ruby code goes here
end
=> true
Parce que ça retourne un booléen.
Comme de nombreux autres exemples montrent que vous n'avez pas réellement 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 "la fausseté révèle la vérité".
› irb
>> a = nil
=> nil
>> defined?(a)
=> "local-variable"
>> defined?(b)
=> nil
>> !!defined?(a)
=> true
>> !!defined?(b)
=> false
Pourquoi il n'est généralement pas rentable de 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ù cela compte car il s’appuie sur la contrainte implicite de la valeur booléenne sur 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
Il convient de mentionner que l'utilisation de 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']
sera évalué à la chaîne "method"
, ainsi 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')
Veuillez noter la distinction entre "défini" et "assigné".
$ Ruby -e 'def f; if 1>2; x=99; end;p x, defined? x; end;f'
nil
"local-variable"
x est défini même s'il n'est jamais assigné!
defined?
est excellent, mais si vous êtes dans un environnement Rails, vous pouvez également utiliser try
, en particulier dans les cas où vous souhaitez vérifier un nom de variable dynamique:
foo = 1
my_foo = "foo"
my_bar = "bar"
try(:foo) # => 1
try(:bar) # => nil
try(my_foo) # => 1
try(my_bar) # => nil
En outre, vous pouvez vérifier si elle est définie dans une chaîne via une 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 retournera simplement un avertissement indiquant que la variable n'est pas initialisée.
J'espère que cela t'aides! :)