Ruby2.0の新機能

Rubyの最新バージョンは2014年5月現在、2.1.2です。 Ruby2.0は、いまから1年以上前の2013年2月にリリースされました。

Ruby 2.0.0-p0 リリース

パフォーマンスが改善されているほか、

  • キーワード引数
  • Enumerator::LazyクラスおよびEnumerable#lazyメソッド
  • Module#prependとRefinement
  • シンボル配列リテラル %i

など、いくつかの新機能が盛り込まれています。1.8から1.9ほどの大きな変化はなく、後方互換性に配慮したバージョンアップとなっています。

今回の記事では、Rubyで遅延ストリームを実現するEnumerator::Lazyを紹介します。

Enumerable#lazyで何が出来るか

具体的なイメージを固めるために、Enumerable#lazyメソッドを使う簡単な例を紹介します。

まず、1から100までの整数の中から素数を抜き出すコードは次のように書けます。

小さい方から100個の素数を取得したいときはどうすれば良いでしょうか。

1ずつ数を増やしながら素数かどうかを判定し、素数が100個溜まったところで停止させるというのもひとつのやり方ですが、先に(1..100)に対して行ったような関数型言語のスタイルをここでも使ってみましょう。 1からFloat::INFINITYまでのrangeの中から素数を抜き出し、最初100個を取得(take(100))するコードは次のように書けます。

これを実行すると、無限長配列の全要素について素数かどうかの判定を行い、いつまで待っても結果が帰ってきません。 欲しいのは最初の100個なのだから、必要な分だけ素数判定を行い、100個の結果を返すようにできないものでしょうか。

そこで使えるのがRuby 2.0の新機能Enumerable#lazyメソッドです。これを(1..Float::INFINITY)の後に挟めば、次のように小さい方から100個の素数を求めることが出来ます。

次のページでは、Enumerator::Lazyクラスがどのような仕組みになっているか簡単に解説して行きます。