Ruby/Rubyの基礎知識

Ruby2.0の新機能、Enumerator::Lazyで遅延リストを扱う(2ページ目)

Ruby2.0から導入されたEnumerator::Lazyを使って、無限、あるいは巨大なストリームデータを扱う方法を紹介します。

橋本 拓也

執筆者:橋本 拓也

Rubyガイド

Enumerable#lazyメソッドとEnumerator::Lazyクラス

前ページの最後の例で、to_aを付けていたことに気付かれたでしょうか。これを外すと、結果の素数リストではなく何やら妙なオブジェクトが返ってきます。

これは入れ子になったEnumerator::Lazyクラスのインスタンスです。Enumerableモジュールをincludeしたクラス(たとえばArray, Hashなど)のインスタンスに対してEnumerable#lazyメソッドを使うと、Enumerator::Lazyクラスのオブジェクトが返されます。

Enumerator::LazyEnumeratorのサブクラスとなっています。

Enumerator::Lazyではmap, selectといったEnumeratorに属するメソッドがオーバーライドされており、

これらのメソッドを使うと、すぐに結果を返すのではなく「あとでやる処理」として積み重ねられていきます。先の素数100個の例で得られた返り値をもう一度見てみましょう。

まず中心に1..InfinityEnumerator::Lazyオブジェクトがあり、それに対してselectをかけ、take(100)しているのがわかります。「あとでやる処理」の予定リストであり、to_aを付けるとしぶしぶ処理を実行して必要なだけの結果を返していたのです。ちなみにto_aにはforceというエイリアスも設定されています。

遅延評価について

このように、必要になるまで処理を実行しない評価手法を「遅延評価」と言います。

Enumerable#lazy を使うと、いままで map でできなかった「無限に続く列」や「巨大な列」、そして「終わりの分からない列」を対象として、map や select などの慣れ親しんだインターフェイスで操作できるようになります。

Rubyist Magazine - 無限リストを map 可能にする Enumerable#lazy

Enumerator::Lazyは、既存のRuby言語仕様の上にうまく遅延評価の仕組みを組み入れたライブラリです。

【編集部おすすめの購入サイト】
楽天市場で Ruby 関連の書籍を見るAmazon で Ruby 関連の書籍を見る
  • 前のページへ
  • 1
  • 2
※記事内容は執筆時点のものです。最新の内容をご確認ください。
※OSやアプリ、ソフトのバージョンによっては画面表示、操作方法が異なる可能性があります。

あわせて読みたい

あなたにオススメ

    表示について

    カテゴリー一覧

    All Aboutサービス・メディア

    All About公式SNS
    日々の生活や仕事を楽しむための情報を毎日お届けします。
    公式SNS一覧
    © All About, Inc. All rights reserved. 掲載の記事・写真・イラストなど、すべてのコンテンツの無断複写・転載・公衆送信等を禁じます