Ruby: najbardziej zwięzły sposób użycia zmiennej ENV, jeśli istnieje, w przeciwnym razie użyj domyślnej wartości

W Rubim próbuję napisać wiersz, który używa zmiennej, jeśli została ustawiona, w przeciwnym razie domyślna wartość:

myvar = # assign it to ENV['MY_VAR'], otherwise assign it to 'foobar'

Mógłbym napisać ten kod TAK:

if ENV['MY_VAR'].is_set? #whatever the function is to check if has been set
  myvar = ENV['MY_VAR']
else
  myvar = 'foobar'
end

Ale to jest dość gadatliwe, i staram się napisać to w jak najbardziej zwięzły sposób. Jak mogę to zrobić?

 61
Author: Joshua Pinter, 2011-10-05

9 answers

myvar = ENV['MY_VAR'] || 'foobar'

N. B. Jest to nieco niepoprawne (jeśli hash może zawierać wartość nil), ale ponieważ ENV zawiera tylko ciągi znaków, jest to prawdopodobnie wystarczająco dobre.

 84
Author: undur_gongor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-05 19:06:47

Najbardziej niezawodnym sposobem dla ogólnego Hasha jest pytanie, czy ma klucz:

myvar = h.has_key?('MY_VAR') ? h['MY_VAR'] : 'default'

Jeśli nie dbasz o wartości nil lub false (tzn. chcesz traktować je tak samo jak "nie ma"), to podejście undur_gongora jest dobre (powinno być również dobre, gdy h jest ENV):

myvar = h['MY_VAR'] || 'foobar'

I jeśli chcesz, aby nil było w Twoim hashu, ale udawaj, że go nie ma (tzn. wartość nil jest taka sama jak" nie ma"), jednocześnie zezwalając na false w Twoim hashu:

myvar = h['MY_VAR'].nil? ? 'foobar' : h['MY_VAR']

In the end to naprawdę zależy od Twojej dokładnej intencji i powinieneś wybrać podejście, które pasuje do twoich intencji. Wybór pomiędzy if/else/end i ? : jest oczywiście kwestią gustu, a "zwięzłość" nie oznacza "najmniejszej liczby znaków", więc możesz użyć trójnika lub if bloku zgodnie z życzeniem.

 39
Author: mu is too short,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-02 08:12:24
hash.fetch(key) { default_value }

Zwróci wartość, jeśli istnieje, i zwróci default_value, Jeśli klucz nie istnieje.

 27
Author: Andrew Grimm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-05 21:45:23

Chociaż nie jest to istotne w konkretnym przykładzie, który podałeś, ponieważ naprawdę pytasz o klucze hashowe, a nie o zmienne, Ruby daje sposób na sprawdzenie definicji zmiennej. Użyj słowa kluczowego defined? (nie jest to metoda, ale słowo kluczowe, ponieważ wymaga specjalnej obsługi przez interpreter), tak:

a = 1
defined? a
  #=> "local-variable"

@a = 2
defined? @a
  #=> "instance-variable"

@@a = 3
defined? @@a
  #=> "class-variable"

defined? blahblahblah
  #=> nil

Stąd można:

var = defined?(var) ? var : "default value here"

Z tego co wiem, to jedyny inny sposób niż brzydka begin/rescue/end blok, aby zdefiniować zmienną w sposób, w jaki zapytasz, nie ryzykując NameError. Tak jak powiedziałem, Nie dotyczy to hashów od:

hash = {?a => 2, ?b => 3}
defined? hash[?c]
  #=> "method"

Czyli sprawdzasz, czy metoda [] jest zdefiniowana, a nie para klucz / wartość, do której masz dostęp.

 4
Author: Carl Suster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-06 00:43:21
myvar = ENV.fetch('MY_VAR') { 'foobar' }

'foobar' jest domyślną wartością, jeśli ENV['MY_VAR'] jest wyłączona.

 4
Author: Firefishy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-09 12:38:20

To działa najlepiej dla mnie:

ENV.fetch('VAR_NAME',"5445")
 4
Author: AvremyC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-19 04:50:14

Inna możliwa alternatywa, która będzie działać nawet jeśli ENV ['MY_VAR'] zmieni wartość na false

myvar  = ENV['MY_VAR'].presence || 'foobar'
 2
Author: Bhavya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-29 06:27:02

Żądanie klejnot, który napisałem pozwala to być niezwykle zwięzłe i suche:

myvar = demand(ENV['MY_VAR'], 'foobar')

To użyje ENV['MY_VAR'] tylko wtedy, gdy jest obecny. Oznacza to, że odrzuci go tylko wtedy, gdy jest nil, pusty lub ciąg znaków z białymi spacjami, podając zamiast tego wartość domyślną.

Jeśli poprawna wartość dla ENV['MY_VAR'] jest fałszywa (np. false) lub nieprawidłowa wartość jest prawdziwa (np. ""), to rozwiązania takie jak użycie || nie będą działać.

 1
Author: Convincible,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-09 15:20:16

myvar = ENV['MY_VAR'].is_set? ? ENV['MY_VAR'] : 'foobar'

W ten sposób zachowujesz metodę. is_set?.

 -1
Author: Koof,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-05 19:23:03