开发者

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

开发者 https://www.devze.com 2023-04-10 18:11 出处:网络
In Ruby, I am trying to write a line that uses a variable if it has been set, otherwise default to some value:

In Ruby, I am trying to write a line that uses a variable if it has been set, otherwise default to some value:

myvar = # 开发者_如何学Pythonassign 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?


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.


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.


hash.fetch(key) { default_value }

Will return the value if it exists, and return default_value if the key doesn't exist.


This works best for me:

ENV.fetch('VAR_NAME',"5445")


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

'foobar' being the default if ENV['MY_VAR'] is unset.


Although it's not relevant in the specific example you gave since you're really asking about hash keys, not variables, Ruby does give a way to check variable definition. Use the defined? keyword (it's not a method, but a keyword since it needs special handling by the interpreter), like so:

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

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

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

defined? blahblahblah
  #=> nil

Hence you could do:

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

As far as I know, that's the only way other than an ugly begin/rescue/end block to define a variable in the way that you ask without risking a NameError. As I said, this doesn't apply to hashes since:

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

i.e. you're checking that the method [] is defined rather than the key/value pair you're using it to access.


Another possible alternative, which will work even if ENV['MY_VAR'] turnsout to be a false value

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


The Demand gem which I wrote allows this to be extremely concise and DRY:

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

This will use ENV['MY_VAR'] only if it is present. That is, it will discard it just if it's nil, empty or a whitespace-only string, giving the default instead.

If a valid value for ENV['MY_VAR'] is falsy (such as false), or an invalid value is truthy (such as ""), then solutions like using || would not work.


I am new guy to Ruby, post the answer I found at 2021, maybe useful for someone.

check if env key exists:

 include?(name) → true or false
 has_key?(name) → true or false
 member?(name) → true or false
 key?(name) → true or false

get env with default value:

 ENV.fetch(name, :default_val)

ref: https://docs.ruby-lang.org/en/master/ENV.html


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

This way you keep the .is_set? method.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号