この記事は ESM アドベントカレンダー 2022 の1日目です。
今日のお仕事で Array#sum
を適用できるコードを見かけたので、そのときのリファクタリングのステップをサンプルコードを使って書いてみます。
サンプルコードは Item#price
の合計値を求めるものです。Ruby 2.4 で Array#sum
が導入されるまで、こういった計算には inject
が使われていた名残りっぽい感じで見かけます。
items.inject(0) { |sum, item| sum + item.price }
合計なので sum
というメソッド名で意図が明確になるよう Array#sum
に置換するとこうなります。まずブロック引数を減らせました。
items.sum(0) { |item| item.price }
Array#sum
の初期値の引数はデフォルトで 0 なのでそちらも消せます。
items.sum { |item| item.price }
ここまできたら見慣れた symbol proc に置換するとさっぱりしそうですね。
items.sum(&:price)
どうでしょう。必要最小限の items
, sum
, price
に絞ったシンプルなコードになりました。
Hash の値を集計したい以下のような場合も values
を介して Array#sum
を使うとシンプルになります。
- hash.inject(0) { |sum, (_, v)| sum + v } + hash.values.sum
以上、Array#sum
を使った Ruby リファクタリングの小技でした。
これを RuboCop で検出とオートコレクトできると便利そうなので、そのうち Performance/Sum
cop についても拡張しておこうと思います。いまだと (inject|reduce).0
あたりの正規表現での grep でヒットしたコードを見てみると良いでしょう。
永和システムマネジメントでは、Ruby とアジャイルソフトウェア開発を通じてコミュニティと成長したいエンジニアを絶賛募集しています。