Ruby: Most concise way to use an ENV variable if it exists, otherwise use default value
Solution 1
myvar = ENV['MY_VAR'] || 'foobar'
N.B. This is slightly incorrect (if the hash can contain the value nil
) but since ENV
contains just strings it is probably good enough.
Solution 2
The most reliable way for a general Hash is to ask if it has the key:
myvar = h.has_key?('MY_VAR') ? h['MY_VAR'] : 'default'
If you don't care about nil
or false
values (i.e. you want to treat them the same as "not there"), then undur_gongor's approach is good (this should also be fine when h
is ENV
):
myvar = h['MY_VAR'] || 'foobar'
And if you want to allow nil
to be in your Hash but pretend it isn't there (i.e. a nil
value is the same as "not there") while allowing a false
in your Hash:
myvar = h['MY_VAR'].nil? ? 'foobar' : h['MY_VAR']
In the end it really depends on your precise intent and you should choose the approach that matches your intent. The choice between if/else/end
and ? :
is, of course, a matter of taste and "concise" doesn't mean "least number of characters" so feel free to use a ternary or if
block as desired.
Solution 3
hash.fetch(key) { default_value }
Will return the value if it exists, and return default_value
if the key doesn't exist.
Solution 4
This works best for me:
ENV.fetch('VAR_NAME',"5445")
Solution 5
myvar = ENV.fetch('MY_VAR') { 'foobar' }
'foobar'
being the default if ENV['MY_VAR']
is unset.
Mike
Updated on September 08, 2021Comments
-
Mike almost 3 years
In Ruby, I am trying to write a line that uses a variable if it has been set, otherwise default to some value:
myvar = # assign it to ENV['MY_VAR'], otherwise assign it to 'foobar'
I could write this code like this:
if ENV['MY_VAR'].is_set? #whatever the function is to check if has been set myvar = ENV['MY_VAR'] else myvar = 'foobar' end
But this is rather verbose, and I'm trying to write it in the most concise way possible. How can I do this?
-
mu is too short over 12 yearsOr
hash.fetch(key, default_value)
if the default doesn't depend on the key. -
oligan over 12 years@mu is too short: Yes. Usually I'm doing
hash.fetch(key) { raise "#{key.inspect} doesn't exist!" }
, so I wasn't 100% sure of the correct order when there's two parameters. -
mu is too short over 12 yearsI (like almost everyone else it seems) tend to forget that
fetch
even exists so +1 for using the whole API. -
oligan over 12 years@muistooshort: Why don't most people use it? Is it because it's too long, or because the tutorials don't teach it?
-
mu is too short over 12 yearsProbably the same reason no one uses
Array#at
: they don't know about it, tutorials don't cover it, they think "concise" means "short", they think a mess of symbols is more Rubyish than a method call, etc. Programmers are as much victims of group-think and habit as anyone else despite the individualistic streak that a lot of programmers like to think they have. But now we're wondering into programmers.stackexchange.com territory and risking heresy. -
oligan over 12 years@muistooshort: Why would you use
at
? Because it's more English-like, or because it accepts fewer types of arguments? -
mu is too short over 12 yearsI can't think of a non-artificial reason right now. I do prefer
a.push(x)
overa << x
though (possibly due to bad experiences with people over-doing operator overloading C++). -
Mike almost 12 yearsIs
is_set?
a ruby method? I thought I made that up because I didn't know the name of the method I was asking for. -
Christopher Ian Stern almost 9 yearsAt least in my version of ruby there is no is_set?, there is a ENV.has_key?
-
theUtherSide almost 9 yearsDittos @undur_gongor. Thanks for being thorough!
-
Joshua Pinter over 5 yearsHow does this handle empty strings,
""
? For example if I set my ENV variable withMY_VAR= rails s
, wouldmyvar
get set to""
or would it get set to"foobar"
? -
Joshua Pinter over 5 yearsAnswer: It will get set to an empty string,
""
. Depending on what you're going for, that could be the desired result. If not, you can also useENV.key?( "MY_VAR" )
to see if the variable is set at all? -
Admin over 4 yearsStrange! how is that? could you please edit your answer to tell us some details about it?
-
CanuckT almost 4 yearsFor the
h
in the code above - is that just a temporary value forhash
or should we be relatingh
with something from our code/names? -
mu is too short almost 4 years@CanuckT
h
is a generic hash, could be any hash at all. I think I usedh
rather thanENV
because there's nothing specific toENV
or how it behaves, it is just about hashes. -
funder7 almost 3 yearsI've found more details in this answer: stackoverflow.com/questions/47985660/… - Cheers