如何在ruby中正确地保存此语句?

如何在ruby中正确地保存此语句?,ruby,chef-infra,rubocop,Ruby,Chef Infra,Rubocop,我有一个厨师资源,我刚刚在食谱中添加了带有烹饪风格的linting。我在食谱中有这样一句话: existing_value = key.to_s.split('.').inject(node.elasticsearch) { |result, attr| result[attr] } rescue nil if existing_value.nil? 这导致了过梁的错误。我试过几次,但我不知道如何说同样的话并通过皮棉测试 Style/RescueModifier: Avoid using r

我有一个厨师资源,我刚刚在食谱中添加了带有烹饪风格的linting。我在食谱中有这样一句话:

existing_value = key.to_s.split('.').inject(node.elasticsearch) { |result, attr| result[attr] } rescue nil if existing_value.nil?
这导致了过梁的错误。我试过几次,但我不知道如何说同样的话并通过皮棉测试

 Style/RescueModifier: Avoid using rescue in its modifier form
如果我完全删除rescue语句,则会导致此异常:

Chef::Mixin::Template::TemplateError (undefined method `[]' for nil:NilClass) on line #52:
    ...
    52: <%= print_value 'action.destructive_requires_name' -%>        
    ...

所以,如果你使用的是最近的厨师版本,我们实际上有一种方法。您可以这样做:

existing_value ||= node.read("elasticsearch.#{key}")  

剩下的我们会处理。

虽然coderanger的解决方案更好,但linter希望您使用长救援表单

begin
  existing_value = key.to_s.split('.').inject(node.elasticsearch) { |result, attr| result[attr] } 
rescue 
  nil
end if existing_value.nil?
或者通常认为更好

if existing_value.nil?
  begin
    existing_value = key.to_s.split('.').inject(node.elasticsearch) { |result, attr| result[attr] } 
  rescue 
    nil
  end
end

我还将rescue更改为更具体的rescue Chef::Mixin::Template::TemplateError,拯救所有异常可能不是您想要的,也就是说,您不想隐藏一个真正的异常

,这是一个全面拯救,在实践中非常糟糕。你能移除rescue nil部件并使其继续工作吗?如果没有,它会引发什么异常?key的值是多少?请阅读和链接页面。错误告诉我们结果是nil。在这个例子中,键的值,第52行action.contractive_requires_name是nil,它在我发布的异常的输出中。一个小问题,请不要使用chefstyle,那就是Chef本身。你想使用烹饪风格,这是烹饪书。它实际上是烹饪风格。我的错误。实际的异常是不同的,我们只是包装所有来自Erb的错误,以便它们以一些特殊的逻辑显示。有无数的文章解释了为什么这是一件坏事。例如,您不应该捕获SystemExit或OutOfMemory错误,因为抛出这些错误还有其他原因。您至少应该将其限制为StandardError的子类