yield でイテレータを独自に定義
お金 | 仕事 | 勉強 | プライベート | 健康 | 心
プログラミング関連のコンテンツ
C言語/C++入門 | Ruby入門 | Python入門 | プログラミング全般
Rubyに独特な機能として、カスタマイズしたイテレータを自分で定義できる点があります。
yield というメソッドを用いて、イテレータメソッドからブロックへと処理を戻し、ブロック終端まで処理が進んだら、イテレータメソッドへ制御を移し、yieldの次の文から実行が再開される。
これを繰り返すことで、ループが進むわけですが、文章で書くと難しいので、実例を見てみます。
例として、Arrayクラス(配列)のイテレータを独自定義してみます。
機能としては、数字の要素からなる配列を受け取り、各々の要素を2倍するeach_twiceメソッドです。
class Array def each_twice i = 0 while i < self.length x = self[i] * 2 yield x i += 1 end end end d_ary = [0, 4, 5, 7, 9, 32] d_ary.each_twice do |x| puts x end
実行結果。
0 8 10 14 18 64
配列 d_ary の要素がそれぞれ2倍されて、出力されています。
each_twice が、独自に定義したイテレータメソッドとなるわけですが、このメソッドが呼ばれたときに、yield 処理の流れは以下の通りとなります。
1.d_ary.each_twice・・・により、イテレータメソッドeach_twiceが呼び出される。
2.each_twice は、while i < self.length の条件を満たす間、つまりd_ary の要素数だけループ。
3.x = self[i] * 2 により、d_ary の要素が2倍にされる。
4.yield x により、イテレータメソッドの呼び出し元のコードブロック(do |x| puts x end)へと処理が戻り、x(2倍にされた配列の要素)をブロックに渡す。
5.puts x が実行され、x(2倍にされた配列の要素)が出力される。
6.do |x| puts x end のコードブロックがendに達した時点で、処理がイテレータメソッドの”yield x”の次の行へと移る。
7.”yield x”の次の行からが実行され、以下繰り返し。
こんな感じの流れで、イテレータメソッドと呼び出し元のコードブロックで処理が行ったり来たりしながら、繰り返しが進むことになります。
上記と同じ働きを持つイテレータメソッドは、while を用いずに、eachを使ってもできる。
class Array def each_twice2 self.each do |x| x *= 2 yield x end end end
実行結果は、同じです。
- - 関連記事 -
- 引数のあるイテレータ
- イテレータ定義で複数の引数をブロックに渡す
- クラス内にイテレータ定義
- イテレータを定義する・まずは未定義のクラスの例
- grepとsort_byメソッド・Enumerableモジュール
- ファイルをイテレータ処理
- イテレータとは