首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为Rubocop重构两个以上级别的块嵌套

为Rubocop重构两个以上级别的块嵌套
EN

Stack Overflow用户
提问于 2015-07-03 12:40:58
回答 1查看 4.2K关注 0票数 3

我正在努力使我的Ruby代码更好,特别是在按照Ruby成语对其进行样式化方面。我有以下方法:

代码语言:javascript
复制
def self.carnivore_convert
  lambda do |value, field|
    diet_type = value
    if field[:header].to_s == 'diet'
      diet_value = value.to_s.downcase
      if diet_value =~ /yes|no/
        diet_value == 'yes' ? diet_type = 'Carnivore' : diet_type = ''
      end
    end
    diet_type
  end
end

鲁波克抱怨说,我应该:

“避免超过两个层次的块嵌套。”

它具体指的是这一行:

代码语言:javascript
复制
diet_value == 'yes' ? diet_type = 'Carnivore' : diet_type = ''

然而,我一点也不清楚为什么这是一种“风格违规”,而我为“修复”所做的任何事情似乎都会使代码更加混乱,至少在我看来是这样的。

当我说我不明白为什么这会违反风格的时候,我明白Rubocop显然觉得我不应该使用if...if...if排序结构。但我不知道为什么这样做是错的。

我在想,也许我可以通过使用一种保护子句来消除代码中的第一个if条件,但是我不能这样做,因为这样我的代码就不能工作了。例如,我修改了代码如下:

代码语言:javascript
复制
def self.carnivore_convert
  lambda do |value, field|
    diet_type = value
    next unless field[:header].to_s == 'diet'
    diet_value = value.to_s.downcase
    if diet_value =~ /yes|no/
      diet_value == 'yes' ? diet_type = 'Carnivore' : diet_type = ''
    end
    diet_type
  end
end

但是,虽然没有出错,但这确实使代码无法按预期工作。我尝试了breakreturn,而不是next

因此,我不知道如何将这段代码变成一个Rubocop不会抱怨的形状,而且它仍然是可读的。作为一个附带问题,我觉得我花了很多时间在"Ruby样式化“上,即使我有绝对有效的代码。只要我能理解为什么风格是违法的,我不介意,但在这里,我有困难看到它。话虽如此,我已经学会了,我要建立我对这些东西的直觉还有很长的路要走。

关于上述问题,有人有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-03 13:48:30

如果你收到嵌套警告,这基本上意味着“这里有太多事情发生了”。有时,样式还会出现其他问题,您可以修复它们(例如,保卫子句)。其他时候你只需要拆分代码。方法和类越小,其可读性就越强,并且可能承担单一的责任。下面的代码远非十全十美,但它只是为了显示一个简单的更改,使其更具可读性,并遵循约束:

代码语言:javascript
复制
def self.carnivore_convert
  lambda do |value, field|
    field[:header].to_s == 'diet' ? diet_type(value) || value : value
  end
end

def self.diet_type(diet_value)
  diet_value = diet_value.to_s.downcase
  if diet_value =~ /yes|no/
    diet_value == 'yes' ? 'Carnivore' : ''
  end
end
private_class_method :diet_type

编辑:这里的是另一个版本,它相当于原始代码,但更容易掌握:

代码语言:javascript
复制
def self.carnivore_convert
  lambda do |value, field|
    simplified_value = value.to_s.downcase

    if diet_header?(field) && simplified_value == 'yes'
      'Carnivore'
    elsif diet_header?(field) && simplified_value =~ /yes|no/
      ''
    else
      value
    end
  end
end

def self.diet_header?(field)
  field[:header].to_s == 'diet'
end
private_class_method :diet_header?
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31207152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档