標準添付ライブラリ紹介 【第 5 回】 enumerator
初稿:2005-11-16
書いた人:西山
はじめに
この連載について
Ruby 1.8 になって標準添付ライブラリが増えました。そんなライブラリをどんどん紹介していこうという連載です。
今回の記事について
今回は enumerator を紹介します。
ruby 1.9 では既に組み込みとなっていて、
今後はより広く一般的に用いられるようになると思われるライブラリです。
enumerator とは?
Enumerable モジュールに含まれるすべてのメソッドは、
each メソッドを利用して実現されています。
例えば、通常は String#each を用いて行毎にインデックス付きで繰り返す
String#each_with_index で、String#each の代わりに
String#each_byte を利用してバイト毎に処理してみたいと思ったことはありませんか?
IO.foreach などで each_with_index や collect などの
Enumerable モジュールのメソッドを利用したいと思ったことはありませんか?
それを叶えるために enumerator が作られました。
使用例
一番簡単な例は Object#enum_for で each の代わりに使いたいメソッドを指定して、Enumerable モジュールのメソッドを続けるだけです。
コメントに書いてあるものは出力例です。
enum_for を使わない場合は、このようになります。
引数を必要とするメソッドでは、enum_for の第 2 引数以降に指定すれば
そのままメソッド (下の例では each_slice) に渡されます。
enum_for を使わない場合は、このようになります。
each_slice が enumerator ライブラリで定義されているメソッドなので、
require は残しています。
クラスメソッドでも同じように使えます。
enum_for を使わない場合は、このようになります。
enumerator で追加されるクラスやメソッド
enumerator を require することによって、
- Enumerable::Enumerator クラス
- Object#to_enum(method_name = :each, *args)
- Object#enum_for(method_name = :each, *args)
- Enumerable#enum_with_index など
が追加されます。
ruby 1.9 (2005-07-15) 以降では組み込みになったため、
require する必要はありません。
Enumerable::Enumerator
使用例では説明を省略していましたが、Object#enum_for(または Object#to_enum)で Enumerable::Enumerator オブジェクトが生成されます。
Enumerable::Enumerator オブジェクトの生成は、以下の 3 通りあります。どれも同じ意味になります。
使用例の例で言うと、それぞれ以下の 3 つずつが同じ意味になります。
そして、以下の 2 つが同じ意味になります。
上の enum1, enum2, enum3 の例でいうと、
それぞれ以下の 2 つずつが同じ意味になります。
Enumerable::Enumerator は Enumerable をインクルードしているので、each の他に Enumerable のメソッドも使えます。
そのため、以下のような書き方が出来ます。
途中の enum1 などの変数を使わずに書くと、
使用例のところに出てきたような書き方になります。
Enumerable に追加されるメソッド
enumerator を require すると、
以下のメソッドが Enumerable に追加されます。
- enum_ 系
- Enumerable#enum_cons(n)
- Enumerable#enum_slice(n)
- Enumerable#enum_with_index
- each_ 系
- Enumerable#each_cons(n) {…}
- Enumerable#each_slice(n) {…}
enum_ が頭についているメソッドは Enumerable::Enumerator を生成するメソッドになります。
each_ が頭についているメソッドは each と同じように繰り返すメソッドで、Enumerable::Enumerator とは直接の関係はないメソッドですが、
あると便利なので enumerator で定義されています。
each_slice と each_cons は、どちらも n 要素ずつ繰り返すメソッドです。
違いは言葉で説明するよりも、以下の使用例を見た方がわかりやすいと思います。
終わりに
今回は便利そうなのに意外と使われていないような気がする enumerator を紹介してみました。
関連リンク
著者について
西山和広。
Ruby hotlinks 五月雨版
や
Ruby リファレンスマニュアル
のメンテナをやっています。
Ruby リファレンスマニュアル
はいつでも執筆者募集中です。
何かあれば、マニュアル執筆編集に関する議論をするためのメーリングリスト rubyist@freeml.com(参加方法)へどうぞ。
標準添付ライブラリ紹介 連載一覧