まつもと ゆきひろです
In message "[ruby-list:13541] iterator <-> cursor (Re: iterator for Dummies)"
on 99/04/09, Inaba Hiroto <inaba / sdd.tokyo-sc.toshiba.co.jp> writes:
|> Rubyでもスマートな方法はないんじゃないかと思うのですが、スレッド
|> を使えばできないことはないですね。
|
|1.3系なら, スレッドより遅いですけどcallccでもできるみたいです.
おおっ,気が付かなかった.でも,eachが末端でnilを返すことを
期待してません?
参考までに私がスレッドを使って書いた外部イテレータ(カーソル)
を載せておきますです.
--
class ExternalIterator
def initialize(src)
@src = src
@que = []
first
end
def first
if @thread
@thread.exit
end
@thread = Thread.start {
for i in @src
@que.push i
Thread.stop
end
}
succ
end
def succ
raise 'no more items' unless more
@que.pop
end
alias next succ
def more
while @que.empty?
return false unless @thread.alive?
@thread.run
end
true
end
def each()
while more
yield succ
end
end
end
#<ExternalIteratorサンプル>
def match_items(a, b)
ia = ExternalIterator.new(a)
ib = ExternalIterator.new(b)
i = 0
item_a = ia.first
item_b = ib.first
loop do
if item_a != item_b
printf "collections differ on %dth item\n", i
return
end
i+=1
unless ia.more
if ib.more
printf "collections `a' shorter than `b'(size %d)\n", i
return
end
break
end
unless ib.more
if ia.more
printf "collections `b' shorter than `a'(size %d)\n", i
return
end
break
end
item_a = ia.next
item_b = ib.next
end
printf "collections `a' and `b' are same(size %d)\n", i
end
match_items([1,2,3,4,5],[1,2,8,9,0])
match_items([1,2,3,4],[1,2])
match_items([1,2],[1,2,8,9,0])
match_items([1,2],[1,2,8,9,0])
match_items([1,2,3,4,5],[1,2,3,4,5])
match_items([1,2,3,4,5],[1,2,3,4,4])
match_items({1,2,3,4},{1,2,3,4})
--
実行結果は以下のようになります.
collections differ on 2th item
collections `b' shorter than `a'(size 2)
collections `a' shorter than `b'(size 2)
collections `a' shorter than `b'(size 2)
collections `a' and `b' are same(size 5)
collections differ on 4th item
collections `a' and `b' are same(size 2)