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

実行結果は、同じです。

スポンサーリンク
 
スポンサーリンク