2

私は自分の Ruby コード、特に Ruby のイディオムごとにスタイルを整えるという点で、自分の Ruby コードを改善するために取り組んでいます。私は次の方法を持っています:

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

Rubocop はこれについて不平を言い、次のようにすべきだと言っています。

「2 レベル以上のブロックの入れ子は避けてください。」

具体的には、次の行を参照しています。

diet_value == 'yes' ? diet_type = 'Carnivore' : diet_type = ''

ただし、これが「スタイル違反」である理由についてはまったく明確ではありません。これを「修正」するために行うことは、少なくとも私の見解では、コードが少し面倒になるようです。

なぜそれがスタイル違反なのか理解できないと私が言うとき、Ruboco がどうやら私がif...if...ifソート構造を持つべきではないと感じていることは理解できます。しかし、なぜそれが間違っているのかわかりません。

ある種のガード句を使用して、このコードの最初の if 条件をおそらく取り除くことができると考えていましたが、コードが機能しないため、それを行うことはできません。たとえば、コードを次のように変更しました。

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

ただし、エラーは発生しませんが、これによりコードが意図したとおりに機能しなくなります。代わりにbreakandも試してみました。returnnext

したがって、このコードを、Rubocop が文句を言わずに読み取り可能な形にする方法がわかりません。その副次的な問題として、確実に動作するコードがある場合でも、「Ruby のスタイリング」に多くの時間を費やしているように感じます。スタイルが違反である理由を理解できる限り、私は気にしませんが、ここではそれを見るのに苦労しています。そうは言っても、私は確かに、このようなものに対する直感を構築するには長い道のりがあることを学びました.

上記の問題に関して、誰かアイデアはありますか?

4

1 に答える 1

3

ネストの警告が表示された場合、これは基本的に「ここで行われていることが多すぎる」ことを意味します。スタイルに他の問題があり、それらを修正できる場合があります (たとえば、ガード句など)。それ以外の場合は、コードを分割する必要があります。メソッドとクラスが小さいほど、読みやすくなり、単一の責任を持つ可能性が高くなります。以下のコードは完璧とは言えませんが、読みやすくし、制約に従うための単純な変更を示すことを目的としています。

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

編集:これは元のコードと同等ですが、把握しやすい別のバージョンです:

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?
于 2015-07-03T13:48:30.540 に答える