概要
原著者の許諾を得て翻訳・公開いたします。
- 英語記事: Enumerable avoids using temporary variables when looping - Andy Croll
- 原文公開日: 2018/02/05
- 著者: Andy Croll
Ruby: ループには一時変数ではなくEnumerableを使おう(翻訳)
Rubyで私の大好きな機能のいくつかはEnumerable
モジュールにあります。このモジュールについて詳しくはRubyのドキュメントをどうぞ。
Array
やSet
やHash
などのような「コレクション」を表現するクラスでは、Enumerable
のメソッドや機能が使えます。これらのメソッドを用いることで、そのグループをループで回して、コレクションの個別のメンバーを入力とする操作を行えます。
次のようには書かないこと
C言語のように一時変数を用いてループする。多くの言語ではこれでよしとされている。
total = 0
[1, 3, 5, 7].each do |num|
total += num
end
total
次のように書くこと
RubyのEnumerable
メソッド群への愛を存分に発揮して、#inject
で実装する。
[1, 3, 5, 7].inject(0) do |total, number|
total += number
end
次のように書けばさらに良い
Enumerable
にある便利な#sum
メソッドを用いる。
[1, 3, 5, 7].sum
そうすべき理由
私はRubyを使えば使うほど、Enumerable
のメソッド群を実にエレガントな方法で利用できることに至高の喜びを感じます。このようにコードを構成することでRubyらしい書き方(idiomatic Ruby)になります。Rubyらしく書くことで、Rubyの作法に適った健全なRubyコードを書いていると言えるようになります。
巨大なループを扱う場合、Ruby組み込みのEnumerable
メソッド群を用いることで、メモリ使用量の削減や速度の向上に著しい効果がもたらされることがよくあります。
ループの冒頭でこの手の「一時変数のセットアップ」を見かけたら、そのループをEnumerable
のメソッドで適切に表現する絶好のチャンスと言えるでしょう。
そうすべきではない理由があるとすれば
Ruby経験の浅い人は、#inject
などのメソッドで混乱することもあるようです。こうしたメソッドはRubyを使って得られる基本的なメリットなので、ぜひモノにしましょう。
はてブより
Ruby: ループには一時変数ではなくEnumerableを使おう(翻訳)
- [Ruby]
原文からしてそうだけど、#injectの例はちょっと適切じゃないかな。公式ドキュメントで挙がってる「total + number」の方が良い。ブロックの返り値が次のループのtotalになるので。