クラス内にイテレータ定義
スポンサーリンク
スポンサーリンク
ライフスタイル関連のコンテンツ
お金 | 仕事 | 勉強 | プライベート | 健康 | 心
プログラミング関連のコンテンツ
C言語/C++入門 | Ruby入門 | Python入門 | プログラミング全般
お金 | 仕事 | 勉強 | プライベート | 健康 | 心
プログラミング関連のコンテンツ
C言語/C++入門 | Ruby入門 | Python入門 | プログラミング全般
イテレータを定義する・まずは未定義のクラスの例で、イテレータ未定義のクラスの例を見ました。
スポンサーリンク
注目するのは、「pp proflist」で確認できるProfListのオブジェクトの中身です。
以下のようになっています。
#<ProfList:0x29a2ca0 @proflist= [#<Prof:0x29a2b4c @age=45, @country="America", @name="Tom William">, #<Prof:0x29a2b10 @age=23, @country="Spain", @name="De Pedoro">, #<Prof:0x29a2ad4 @age=37, @country="Japan", @name="Naoko Yamada">]>
オブジェクトのメモリアドレスと、インスタンス変数「@proflist」が配列となっています。
ProfListクラスの中で、以下のように初期化しているので、@proflistが配列であることは当然です。
def initialize() @proflist = Array.new end
クラス内にイテレータを定義する場合には、この配列であるインスタンス変数「@proflist」をレシーバとする、eachメソッドを以下のように定義します。
def each @proflist.each{|prof| yield(prof) } end
yield文がキモとなる部分です。
メソッド定義の中のyield文は、定義しているメソッドに与えられたブロックを実行します。
proflist.each{|prof| puts "#{prof.name} - age:#{prof.age} country:#{prof.country}" }
と、新しく独自定義したイテレータ(eachメソッド)を呼び出すと・・・
{|prof| puts "#{prof.name} - age:#{prof.age} country:#{prof.country}" }
のブロック部分を、yieldが受け取り実行するようなイメージです。
これで、クラス内に新しいイテレータを定義できました。
以下、改良したクラスとテストルーチンです。
require "pp" # 1人のプロフィールのクラス。名前、年齢、出身国 class Prof attr_accessor :name, :age, :country def initialize(name, age, country=nil) @name = name @age = age @country = country end end # プロフィールのリストのクラス class ProfList def initialize() @proflist = Array.new end # 新しい人を加える def add(prof) @proflist.push(prof) end # 人数を返す def length @proflist.length end # n番目の人を別の人に入れ替える def []=(n, prof) @proflist[n] = prof end # n番目の人を返す def [](n) @proflist[n] end # リストからプロフィールを削除 def delete(prof) @proflist.delete(prof) end # イテレータ定義 def each @proflist.each{|prof| yield(prof) } end end # テストルーチン proflist = ProfList.new # プロフィールをいくつか作る p1 = Prof.new("Tom William", 45, "America") p2 = Prof.new("De Pedoro", 23, "Spain") p3 = Prof.new("Naoko Yamada", 37, "Japan") # プロフィールリストに人(プロフィール)を追加 proflist.add(p1) proflist.add(p2) proflist.add(p3) # プロフィールを1人ずつ表示 proflist.length.times{|i| puts "#{proflist[i].name} - age:#{proflist[i].age} country:#{proflist[i].country}" } # プロフィールを1人ずつ表示。 # 今度はProfListクラスに、新しいイテレータとしてeachメソッドを定義したのでOK。 puts "--- original iterator" proflist.each{|prof| puts "#{prof.name} - age:#{prof.age} country:#{prof.country}" }
実行結果。
Tom William - age:45 country:America De Pedoro - age:23 country:Spain Naoko Yamada - age:37 country:Japan --- original iterator Tom William - age:45 country:America De Pedoro - age:23 country:Spain Naoko Yamada - age:37 country:Japan
スポンサーリンク
>> 次の記事 : イテレータ定義で複数の引数をブロックに渡す
<< 前の記事 : イテレータを定義する・まずは未定義のクラスの例
- - 関連記事 -
- 引数のあるイテレータ
- イテレータ定義で複数の引数をブロックに渡す
- イテレータを定義する・まずは未定義のクラスの例
- grepとsort_byメソッド・Enumerableモジュール
- ファイルをイテレータ処理
- イテレータとは
- yield でイテレータを独自に定義
スポンサーリンク