在Ruby中,我试图编写一个使用变量的行(如果已经设置),否则默认为某个值:
myvar = # assign it to ENV['MY_VAR'], otherwise assign it to 'foobar'
我可以像这样编写这段代码:
if ENV['MY_VAR'].is_set? #whatever the function is to check if has been set
myvar = ENV['MY_VAR']
else
myvar = 'foobar'
end
但这是相当冗长的,我试图以最简洁的方式编写它。我怎样才能做到这一点?
myvar = ENV['MY_VAR'] || 'foobar'
注:这有点不正确(如果哈希值可以包含值nil
),但由于ENV
只包含字符串,因此它可能已经足够了。
一般Hash最可靠的方法是询问它是否有密钥:
myvar = h.has_key?('MY_VAR') ? h['MY_VAR'] : 'default'
如果你不关心nil
或false
值(即你想把它们视为“不存在”),那么undur_gongor的方法是好的(当h
是ENV
时这也应该没问题):
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"
据我所知,这是除了丑陋的begin
/ rescue
/ end
块以外的唯一方法来定义变量,而不会冒着NameError的风险。正如我所说,这不适用于哈希:
hash = {?a => 2, ?b => 3}
defined? hash[?c]
#=> "method"
即,您正在检查是否定义了[]
方法而不是您正在使用它访问的键/值对。
myvar = ENV.fetch('MY_VAR') { 'foobar' }
如果没有设置'foobar'
,ENV['MY_VAR']
是默认值。
另一种可能的替代方案,即使ENV ['MY_VAR']结果为假值也会起作用
myvar = ENV['MY_VAR'].presence || 'foobar'
我写的Demand宝石允许它非常简洁和干燥:
myvar = demand(ENV['MY_VAR'], 'foobar')
只有在存在时才会使用ENV['MY_VAR']
。也就是说,它会丢弃它,只要它是nil,空或只有空格的字符串,而是给出默认值。
如果ENV['MY_VAR']
的有效值是假的(例如false
),或者无效的值是真实的(例如""
),则使用||
的解决方案将无效。
myvar = ENV['MY_VAR'].is_set? ? ENV['MY_VAR'] : 'foobar'
这样你就保留了.is_set?方法。