web-dev-qa-db-fra.com

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- disponible?

560
Readonly

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"
768
Ricardo Acras

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.

90
danmayer

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.

70
foomip

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

18
digitalsanctum

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
15
user761856

Utilisez defined? YourVariable
Soyons simples, bête..;)

9
Saqib R.

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.

7
Sardathrion

AVERTISSEMENT Re: Un motif de rubis commun

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?.

6
BKSpurgeon

Tu peux essayer:

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

Parce que ça retourne un booléen.

5
Bruno Barros

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
3
user325634

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')
3
leberknecht

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é!

2
Robert Klemme

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
0
John Donner

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! :)

0
Elliott