Ruby Freaks Lounge

第1回 Ruby1.9の新機能ひとめぐり(前編):YARV,Fiber,配列処理の強化

この記事を読むのに必要な時間:およそ 3 分

外部イテレータのサポート

Enumeratorには「内部イテレータを外部イテレータ化する」というもうひとつの顔があります。Rubyのブロックは内部イテレータといわれ,⁠イテレータから要素が渡される」のを処理するという書き方になりますが,外部イテレータはその逆で,⁠イテレータから要素を取り出し」て処理するという書き方になります。

コード4 外部イテレータの使用例

# Enumeratorの作成
e = [1, 2, 3].each

# 1つめの要素を取り出す
p e.next #=> 1

# 2つめの要素を取り出す
p e.next #=> 2

# 巻き戻すこともできる
e.rewind

# 巻き戻したら1つめの要素から取り出しなおす
p e.next #=> 1

PythonやC++など,外部イテレータが標準的な言語に慣れた人には合う機能かもしれません。ただし,この機能はFiberを用いて実装されており,内部イテレータに比べて実行速度がかなり遅いことには注意すべきです。

配列関係のメソッド追加

ArrayやEnumerableに便利なメソッドが多数追加されました。シャッフルのように何度も再発明されてきたメソッドや,記述性・可読性を向上させるメソッドです。

順列・組み合わせ系のメソッド
  • 順列を列挙する Array#permutation
  • 組み合わせを列挙する Array#combination
  • 配列と配列の直積を返す Array#product
ランダム系のメソッド
  • 配列をシャッフルする Array#shuffle
  • 配列から要素をランダムに抽出する Array#sample
Haskell に由来するメソッド
  • 先頭n個を取り出す Enumerable#take(ary[0, n] と同じ)
  • 先頭n個を捨てたものを返する Enumerable#drop(ary[n..-1] と同じ)
  • 先頭から条件を満たす限りの要素を取り出す Enumerable#take_while {}
  • 先頭から条件を満たす限りの要素を捨てたものを返す Enumerable#drop_while {}
  • 配列を循環して列挙し続ける Enumerable#cycle(通常は Enumerator 化して使います)

それぞれの詳細はマニュアルを参照してください。

以上の「配列処理の強化」の機能は,あまり周知されていないように思います。⁠YARV」「M17N」のようなキーワードがないことや,1.8.7で1.8系列にもバックポートされたため厳密には1.9の新機能でなくなったことが理由でしょうか。ですが,この機能はコードの再発明を防止し記述性を向上させる非常に優れたものですので,少しでも多くの方に知ってもらいたいと思います。

gemとrakeが組み込みに

従来はサードパーティのツールに過ぎなかったrubygems(Rubyライブラリのパッケージングツール)と,rake(make のようなビルドツール)が標準機能として組み込まれました。

rubygemsはgem installというコマンド一発でライブラリをインストールできる便利なツールです。ただし,現在はまだRuby 1.9に対応していないパッケージも多いため,本領を発揮するには時間がかかりそうです。is it Ruby 1.9というサイトで種々のパッケージが 1.9で動作したかどうかの報告をみることができますので,興味のある方は参照するとよいでしょう。

rakeはmakeのようなツールですが,Makefileに相当するRakefileがRubyによるDSLとして設計されており,Rubyに慣れたユーザなら凝ったことがしやすくなっています。

まとめ

今回は,1.9の最適化と機能拡張を中心に紹介しました。ニュースなどではYARVやM17N といったわかりやすく目立つ機能が取りざたされがちですが,Ruby1.9の真価はそれだけではありません。実際に使い始めると,配列処理の強化が非常に便利であることに気がつくと思います。

次回は,Ruby1.9の洗練された文法を中心に取り上げたいと思います。

著者プロフィール

遠藤侑介(えんどうゆうすけ)

某電機メーカーで研究職勤務。個人活動として,2008年1月よりRubyの開発に参加。テストを書いたり,バグをとったり,バグを入れたりしています。好きな言語はRubyとHaskellとOCaml 。使う言語はRubyとC 。

URLhttp://d.hatena.ne.jp/ku-ma-me/