针对此代码运行Rubocop后,我正在
Use a guard clause instead of wrapping the code inside a conditional expression.
所以从我所看到的情况来看,如果条件不满足,“守卫条款”将会退出该方法,所以我们不必浪费时间通过额外的条件,如果我的理解不正确,请纠正我
我的问题是,我将如何使用具有多个条件的保护声明
def auth_creds
if %w(test1 qa demo ci).include? ENV['ENV']
{ key: 'key1', secret: 'secret1' }
elsif ENV['ENV'] == 'live'
{ key: 'key2', secret: 'secret2' }
else
fail 'Unable to set key/secret'
end
end
由于
答案 0 :(得分:8)
您的代码段不是“防护条款”的有效示例。没有什么可以防范的。它只是选择数据。它看起来更好case/when
,但if
链条也很好。
def auth_creds
case ENV['ENV']
when 'test1', 'qa', 'demo', 'ci'
{ key: 'key1', secret: 'secret1' }
when 'live'
{ key: 'key2', secret: 'secret2' }
else
fail 'Unable to set key/secret'
end
end
当方法的整个主体被包装在条件中时,使用Guard子句(或者我称之为提前返回)。
def process_project
if project
# do stuff
end
end
除非project
,否则该方法不会执行任何操作。因此,如果我们在这里减少嵌套,它会使代码更易读。
def process_project
return unless project
# do stuff with project
end
同样,并非代码中的每个if
都可以/应该转换为此形式。只有在合适的地方。
答案 1 :(得分:3)
这完全取决于您的实际代码,但使用给定的代码段,您可以使用guard子句来确保有效的ENV['ENV']
值:
VALID_ENVS = %w(test1 qa demo ci live)
def auth_creds
fail 'invalid environment' unless VALID_ENVS.include? ENV['ENV']
if ENV['ENV'] == 'live'
{ key: 'key2', secret: 'secret2' }
else
{ key: 'key1', secret: 'secret1' }
end
end
作为noted by Sergio Tulentsev,将您的凭据存储在ENV
(而不是env的名称)可能会更好:
def auth_creds
{ key: ENV.fetch('KEY'), secret: ENV.fetch('SECRET') }
end
如果在fetch
中找不到给定的密钥,则 KeyError
会引发ENV
。
答案 2 :(得分:1)
守卫条款通常如下:
def do_something
return 'x' if some_condition?
# other code
end
因此您的代码可以重写为
def auth_creds
return { key: 'key1', secret: 'secret1' } if %w(test1 qa demo ci).include? ENV['ENV']
return { key: 'key2', secret: 'secret2' } if ENV['ENV'] == 'live'
fail 'Unable to set key/secret'
end
然而,这非常难看,现在rubocop会抱怨太长的线条。因此,让我们重新编写代码来描述其意图:
def auth_creds
return { key: 'key1', secret: 'secret1' } if test_env?
return { key: 'key2', secret: 'secret2' } if live_env?
fail 'Unable to set key/secret'
end
private # omit if `auth_creds` is also private
def test_env?
%w(test1 qa demo ci).include? ENV['ENV']
end
def live_env?
ENV['ENV'] == 'live'
end
奖励积分:将%w(test1 qa demo ci)
提取为常量!
双倍奖励积分(感谢@Sergio Tulentsev)从您的代码中获取您的环境特定(可能是敏感!!!)凭据!如果使用Rails,请将其放在secrets.yml
中,否则请使用众多伟大的宝石之一:
关于Rubocop的一句话:用一粒盐来接受它的建议。例如,您的代码实际上不是保护条款的情况,它只是根据条件返回数据。因此,您也可以尝试将代码重构为case expression。
有时候,Rubocop只是在谈论垃圾:-)(不是故意的,但是"测量"代码风格很难!)