Ruby: 如果存在 ENV 变量,使用它的最简洁方法,否则使用默认值

在 Ruby 中,我尝试编写一行代码,如果已经设置了变量,就使用它,否则默认设置为某个值:

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

但这篇文章相当冗长,我试图用尽可能简洁的方式来写。我怎么能这么做?

50984 次浏览
myvar = ENV['MY_VAR'] || 'foobar'

注意。这有点不正确(如果散列可以包含值 nil) ,但是由于 ENV只包含字符串,所以它可能足够好。

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

This way you keep the .is_set? method.

对于一般 Hash 来说,最可靠的方法是询问它是否拥有密钥:

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

如果你不关心 nil或者 false值(也就是说你想把它们当做“不存在”来对待) ,那么 undur _ gongor 的方法是好的(当 hENV时这也应该是好的) :

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

如果你想让 nil在你的散列中,但是假装它不在那里(也就是说,nil的值和“不在那里”是一样的) ,同时允许 false在你的散列中:

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

最后,它确实取决于你的确切意图,你应该选择与你的意图相匹配的方法。当然,在 if/else/end? :之间进行选择是一个品味问题,“简洁”并不意味着“字符数最少”,因此可以根据需要随意使用三进制或 if块。

hash.fetch(key) { default_value }

将返回存在的值,如果键不存在则返回 default_value

虽然它与您给出的特定示例无关,因为您实际上询问的是散列键,而不是变量,但 Ruby 确实提供了一种检查变量定义的方法。使用 defined?关键字(它不是一个方法,而是一个关键字,因为它需要解释器的特殊处理) ,如下所示:

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


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


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


defined? blahblahblah
#=> nil

因此,你可以这样做:

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"

例如,您正在检查方法 []是否已定义,而不是您使用它来访问的键/值对。

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

如果未设置 ENV['MY_VAR'],则默认为 'foobar'

另一个可能的替代方案,即使 ENV [‘ MY _ VAR’]是一个假值,它也会起作用

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

我所写的 要求版本允许这个非常简洁和干燥:

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

只有在 ENV['MY_VAR']存在的情况下才会使用它。也就是说,如果它是 nil、 null 或者只有空格的字符串,它就会丢弃它,而给出默认值。

如果 ENV['MY_VAR']的有效值是假的(例如 false) ,或者无效值是真的(例如 "") ,那么使用 ||这样的解决方案将不起作用。

这对我最有效:

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

我是 Ruby 的新人,把我在2021年找到的答案贴出来,也许对某些人有用。

检查 env 键是否存在:

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

使用默认值得到 env:

 ENV.fetch(name, :default_val)

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