Ruby: Most concise way to use an ENV variable if it exists, otherwise use default value

46,243

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.

Share:
46,243
Mike
Author by

Mike

Updated on September 08, 2021

Comments

  • Mike
    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
    mu is too short over 12 years
    Or hash.fetch(key, default_value) if the default doesn't depend on the key.
  • oligan
    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
    mu is too short over 12 years
    I (like almost everyone else it seems) tend to forget that fetch even exists so +1 for using the whole API.
  • oligan
    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
    mu is too short over 12 years
    Probably 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
    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
    mu is too short over 12 years
    I can't think of a non-artificial reason right now. I do prefer a.push(x) over a << x though (possibly due to bad experiences with people over-doing operator overloading C++).
  • Mike
    Mike almost 12 years
    Is 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
    Christopher Ian Stern almost 9 years
    At least in my version of ruby there is no is_set?, there is a ENV.has_key?
  • theUtherSide
    theUtherSide almost 9 years
    Dittos @undur_gongor. Thanks for being thorough!
  • Joshua Pinter
    Joshua Pinter over 5 years
    How does this handle empty strings, ""? For example if I set my ENV variable with MY_VAR= rails s, would myvar get set to "" or would it get set to "foobar"?
  • Joshua Pinter
    Joshua Pinter over 5 years
    Answer: 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 use ENV.key?( "MY_VAR" ) to see if the variable is set at all?
  • Admin
    Admin over 4 years
    Strange! how is that? could you please edit your answer to tell us some details about it?
  • CanuckT
    CanuckT almost 4 years
    For the h in the code above - is that just a temporary value for hash or should we be relating h with something from our code/names?
  • mu is too short
    mu is too short almost 4 years
    @CanuckT h is a generic hash, could be any hash at all. I think I used h rather than ENV because there's nothing specific to ENV or how it behaves, it is just about hashes.
  • funder7
    funder7 almost 3 years
    I've found more details in this answer: stackoverflow.com/questions/47985660/… - Cheers