From: matz@... (Yukihiro Matsumoto) Date: 1999-04-09T14:55:37+09:00 Subject: [ruby-list:13542] Re: iterator <-> cursor (Re: iterator for Dummies) まつもと ゆきひろです In message "[ruby-list:13541] iterator <-> cursor (Re: iterator for Dummies)" on 99/04/09, Inaba Hiroto 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 # 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)