読者です 読者をやめる 読者になる 読者になる

Rubyで豊富なイテレータ(ブロック付きメソッド)を使用する理由

ary.each do で全てのケースをカバーできるのに、特別な構文をいくつも用意してタイプ量をわずかに減らすことに何の意味があるのでしょうか?

というコメントをいただいたので,自分なりの考えを述べたいと思う.

様々なイテレータがある理由,これは一言で言えば,「Ruby はコードの美しさに重きを置く言語だから」だ.Ruby のコードは最も読みやすく,最も短く,そして最も美しく書くことが求められる.Ruby のコードはエレガントでなければならないのだ.

これを踏まえた上で,Rubyの豊富なイテレータについて,私の考えるキーワードは3つ.

  1. 生産性
  2. 可読性
  3. 速度

まずは生産性.タイプ量が減るというよりも,やりたいことを最適なイテレータで書ける,やりたいことを直感的に書けるということの方が大きいと思う.

例えば map メソッド.これは配列全ての要素に同じ処理を行って新しい配列を作るというものだ.

文字列の配列を,その長さの配列に変換したいとき,map メソッドを用いて

ary = ["a", "abc", "abcdefg"]
ary.map {|e| e.length}          # => [1, 3, 7]

で書けることを,each を使ってどのように実現するだろうか.map を使えば簡単にできるのに,あえて each を使うのは無駄だし,each でこれ以上わかりやすく美しく書くことは不可能だろう.

これは,可読性にも直結しており,エレガントな Ruby プログラムは(Rubyistにとって)非常に読みやすい.短いコードに何をしたいのかがはっきり表現されている.これは良いソースコードとして大切な条件だ.

また,各イテレータに対して最適化が行えるため,単に each で書くよりも実行速度が早い(はず.間違ってたら申し訳ない).

ちょっとわかりにくいけど非常に便利なinjectメソッド - 勉強日記 でも述べたが,C言語には while 文と for 文が存在し,互いに変換可能である.しかし,while で書けることを for で書くことに意味がないと感じるだろうか.定数回のループであれば,while で書けたとしても私なら for を使う.

Ruby の each メソッドとその他のイテレータの関係は,この while と for に似たものだと私は考えている.どちらでも書けるが,適した場合には each 以外を使った方が嬉しいのだ.

Ruby には非常に豊富なイテレータが存在する.そのそれぞれのイテレータの使用方法などをググって,エレガントな使用例を探してみてほしい.また,それを each で書き直してみてほしい.きっと Rubyイテレータが豊富な理由がさがありがたく感じるはずだ.

each よりも別のイテレータを使う方が読みやすく書きやすい.これが私の考える Ruby の豊富なイテレータを使用する理由である.