web-dev-qa-db-fra.com

Ruby: Manière la plus concise d'utiliser une variable ENV si elle existe, sinon utilisez la valeur par défaut

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?

45
Andrew
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.

58
undur_gongor

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.

33
mu is too short
hash.fetch(key) { default_value }

Renverra la valeur si elle existe et retournera default_value si la clé n'existe pas.

19
Andrew Grimm

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.

4
Carl Suster
myvar = ENV.fetch('MY_VAR') { 'foobar' }

'foobar' étant la valeur par défaut si ENV['MY_VAR'] est désactivé.

2
Firefishy

Une autre alternative possible, qui fonctionnera même si ENV ['MY_VAR'] est une fausse valeur

myvar  = ENV['MY_VAR'].presence || 'foobar'
1
Bc91

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.

0
Convincible