私はいくつかの発見に以下の更新を提供しました...
現在のコードにあるメソッドは次のとおりです。
def query(data_set, conditions)
query_data_set = data_set.dup
search_conditions = parse_conditions(conditions)
search_conditions.each do |condition|
if condition.class == Array
condition.each do |term|
if term.class == Symbol
query_data_set = entity.send term, query_data_set
else
query_data_set = search_data_text(query_data_set, term)
end
end
end
if condition.class == Hash
condition.each do |key, value|
query_data_set = method("query_#{key}").call(data_set, value)
end
end
end
query_data_set
end
Rubocop がこれを嫌う理由は 3 つあります。
C: Assignment Branch Condition size for query is too high. [17.03/15]
def query(data_set, conditions)
C: Method has too many lines. [19/7]
def query(data_set, conditions)
C: Use next to skip iteration.
search_conditions.each do |condition|
イテレーションをスキップしたくないので、なぜ使用するのかまったくわかりませんnext
。このコードでは、反復をスキップすることが理にかなっている場合はありません。
他の苦情に移ると、このメソッドの先頭で、既に 1 つのアクション ( への呼び出しparse_conditions
) が分割されていることがわかります。への呼び出しもありますsearch_data_text
。ここでの私の唯一のポイントは、それが理にかなっていると思われる場合にモジュール化しようとしたことです。
その大きなsearch_conditions.each
ブロックを別のメソッドに移動したとしても、Rubocop は新しいメソッドも長すぎると文句を言うでしょう。これは、 2 番目のメソッドが呼び出す3 番目のメソッドをさらに追加することを意味すると思いますか? それは私には奇妙に思えます。というか、あまり分岐しなくていいということなのかな。しかし、なぜ分岐が悪いのでしょうか? 他の構造 (case...when など) に切り替えても、まだ分岐しています。また、ネストされた配列、シンボルを含む配列、またはハッシュでは処理が異なるため、これらの条件をテストする必要があります。
このような問題を見て、効果的で効率的な解決策を見つけられるように直感を構築しようとしています....しかし、私がやっていることは、ひどく非効率的で時間の無駄です. 私のコードが悪い理由がわからないので、そのトレードオフが心配です。
これを試してみて、上記のメソッドを読みやすさの外観を維持しながらRubyistが好むスタイルガイドラインに適合する状態にする方法を理解するのを手伝ってくれませんか?
---------------------- 更新 ----------------------
私が思いつくことができる最高のものはこれです:
def query(data_set, conditions)
query_data_set = data_set.dup
parse_conditions(conditions).each do |condition|
query_data_set = check_conditions(condition, query_data_set)
end
query_data_set
end
def check_conditions(condition, data)
if condition.class == Array
condition.each do |term|
data = entity.send term, data if term.class == Symbol
data = search_data_text(data, term) unless term.class == Symbol
end
end
if condition.class == Hash
condition.each do |key, value|
data = method("query_#{key}").call(data, value)
end
end
data
end
このcheck_conditions
メソッドは、Rubocop にはまだ長すぎ、分岐条件のサイズが大きすぎます。
私が見る限り、私がチェックしたところはどこにも違いを示すことができませんでしたが、できる唯一のことは、おそらく配列とハッシュのチェックからメソッドを作成することです。つまり、各if
条件はcheck_conditions
独自のメソッドを取得します。しかし、それは私には不必要にばかげているように思えます。私は基本的にロジックを分解し、変数をさまざまなメソッドに渡します。これは、メソッド数を任意の値未満に保つことができるようにするためです。
これは、デザインを行う方法として、私にはかなり間違っているように感じます。しかし、ロジックを変更して必要なことを達成できるようにする方法はわかりませんが、メソッドごとに 7 行未満で実行できます。