web-dev-qa-db-fra.com

Définir Ruby variable si elle n'est pas déjà définie

Dans Ruby, comment définir une variable sur une certaine valeur si elle n'est pas déjà définie et laisser la valeur actuelle si elle est déjà définie?

41
jrdioko

Tandis que x ||= value est une façon de dire "si x contient une valeur de falsey, y compris nil (qui est implicite dans cette construction si x n'est pas défini car il apparaît sur le côté gauche de l'affectation), affectez une valeur à x ", c'est exactement ce qu'il fait.

C'est à peu près équivalent à ce qui suit. (Pourtant, x ||= value ne lancera pas un NameError comme ce code peut et il assignera toujours une valeur à x comme ceci le code ne fonctionne pas - il s'agit de voir x ||= value fonctionne de la même manière pour toute valeur falsey en x, y compris la valeur "par défaut" nil):

if !x
  x = value
end  

Pour voir si la variable n'a vraiment pas été affectée d'une valeur, utilisez le defined? méthode:

>> defined? z
=> nil                                                                  
>> z = nil                                                              
=> nil                                                                  
>> defined? z                                                           
=> "local-variable"                                                     
>> defined? @z                                                          
=> nil                                                                  
>> @z = nil                                                             
=> nil                                                                  
>> defined? @z                                                          
=> "instance-variable" 

Cependant, dans presque tous les cas , en utilisant defined? est une odeur de code. Attention à l'alimentation. Faites le bon choix: donnez des valeurs aux variables avant d'essayer de les utiliser :)

Codage heureux.

47
user166390
@variable ||= "set value if not set"

Ainsi, les variables false seront remplacées

> @test = true 
 => true 
> @test ||= "test"
 => true 
> @test 
 => nil 
> @test ||= "test"
 => "test" 
> @test = false 
 => false 
> @test ||= "test"
 => "test" 
25
thenengah

Comme vous n'avez pas spécifié quel type de variable:

v = v
v ||= 1

Cependant, je ne recommande pas de le faire avec des variables locales.

Edit: En fait, v = v n'est pas nécessaire

7
Victor Moroz

Un peu en retard mais une solution qui n'écrase pas non plus les valeurs de falsey (y compris nil):

# assuming x is not defined in current scope
!defined?(x) ? x = 42 : nil  # => x == 42

y = false
!defined(y) ? y = 42 : nil   # => x == false

z = nil
!defined(z) ? z = 42 : nil   # => z == nil
2
sprestel

Si la variable n'est pas définie (déclarée?), Elle n'existe pas, et si elle est déclarée, alors vous savez comment vous l'avez initialisée, non?

Habituellement, si j'ai juste besoin d'une variable dont je ne connais pas encore l'utilisation --- que je sais jamais utiliser comme booléen --- je l'initialise en définissant sa valeur sur nil. Ensuite, vous pouvez tester si elle a été modifiée ultérieurement assez facilement

x = nil


some code


if x do 
[code that will only run if x has changed]
end

c'est tout.

0
Dmitri