En Ruby, j'essaie d'écrire une ligne qui utilise une variable si elle a été définie, sinon une valeur par défaut:
myvar = # assign it to ENV['MY_VAR'], otherwise assign it to 'foobar'
Je pourrais écrire ce code comme ceci:
if ENV['MY_VAR'].is_set? #whatever the function is to check if has been set
myvar = ENV['MY_VAR']
else
myvar = 'foobar'
end
Mais ceci est plutôt verbeux et j'essaie de l'écrire de la manière la plus concise possible. Comment puis-je faire ceci?
myvar = ENV['MY_VAR'] || 'foobar'
N.B. C'est légèrement incorrect (si le hachage peut contenir la valeur nil
) mais puisque ENV
ne contient que des chaînes, il est probablement suffisant.
Le moyen le plus fiable pour un hachage général est de demander s'il possède la clé:
myvar = h.has_key?('MY_VAR') ? h['MY_VAR'] : 'default'
Si vous ne vous souciez pas des valeurs nil
ou false
(c'est-à-dire que vous voulez les traiter de la même manière que "pas là"), l'approche de undur_gongor est bonne (cela devrait également convenir lorsque h
est ENV
):
myvar = h['MY_VAR'] || 'foobar'
Et si vous souhaitez autoriser nil
à figurer dans votre hachage mais prétendre que ce n’est pas le cas (c.-à-d. Une valeur nil
est identique à "not there") tout en permettant à false
dans votre hachage:
myvar = h['MY_VAR'].nil?? 'foobar' : h['MY_VAR']
En fin de compte, cela dépend vraiment de votre intention précise et vous devez choisir l'approche qui correspond à votre intention. Le choix entre if/else/end
et ? :
est, bien sûr, une question de goût et "concis" ne signifie pas "moins de caractères", alors n'hésitez pas à utiliser un bloc ternaire ou if
comme vous le souhaitez.
hash.fetch(key) { default_value }
Renverra la valeur si elle existe et retournera default_value
si la clé n'existe pas.
Bien que cela ne soit pas pertinent dans l'exemple spécifique que vous avez donné puisque vous vous interrogez vraiment sur les clés de hachage et non sur les variables, Ruby permet de vérifier la définition de variable. Utilisez le mot clé defined?
(ce n'est pas une méthode, mais un mot clé car il nécessite un traitement spécial de la part de l'interprète), comme ceci:
a = 1
defined? a
#=> "local-variable"
@a = 2
defined? @a
#=> "instance-variable"
@@a = 3
defined? @@a
#=> "class-variable"
defined? blahblahblah
#=> nil
Vous pourriez donc faire:
var = defined?(var) ? var : "default value here"
Autant que je sache, c’est le seul moyen autre qu’un vilain bloc begin
/rescue
/end
de définir une variable de la manière que vous demandez sans risquer une NameError. Comme je l'ai dit, cela ne s'applique pas aux hachages puisque:
hash = {?a => 2, ?b => 3}
defined? hash[?c]
#=> "method"
c'est-à-dire que vous vérifiez que la méthode []
est définie plutôt que la paire clé/valeur à laquelle vous l'utilisez.
myvar = ENV.fetch('MY_VAR') { 'foobar' }
'foobar'
étant la valeur par défaut si ENV['MY_VAR']
est désactivé.
Une autre alternative possible, qui fonctionnera même si ENV ['MY_VAR'] est une fausse valeur
myvar = ENV['MY_VAR'].presence || 'foobar'
La demande gem que j’ai écrite permet d’être extrêmement concise et sèche:
myvar = demand(ENV['MY_VAR'], 'foobar')
Ceci utilisera ENV['MY_VAR']
seulement s'il est présent. C'est-à-dire qu'il le supprimera uniquement s'il s'agit d'une chaîne nulle, vide ou d'une chaîne blanche, en donnant la valeur par défaut.
Si une valeur valide pour ENV['MY_VAR']
est falsy (telle que false
) ou qu'une valeur non valide est true (telle que ""
), les solutions telles que l'utilisation de ||
ne fonctionneraient pas.