ESM アジャイル事業部 開発者ブログ

永和システムマネジメント アジャイル事業部の開発者ブログです。

`Array#sum`へのリファクタリング

この記事は ESM アドベントカレンダー 2022 の1日目です。

adventar.org

今日のお仕事で 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 とアジャイルソフトウェア開発を通じてコミュニティと成長したいエンジニアを絶賛募集しています。

agile.esm.co.jp