原です。
In message "[ruby-list:13542] Re: iterator <-> cursor (Re: iterator for Dummies)"
on 99/04/09, Yukihiro Matsumoto <matz / netlab.co.jp> writes:
|
|まつもと ゆきひろです
|参考までに私がスレッドを使って書いた外部イテレータ(カーソル)
|を載せておきますです.
|
|--
|class ExternalIterator
| def initialize(src)
| @src = src
| @que = []
| first
| end
ここの first っていうのは(後ろにもあるけど)、必要なのかなあ。
これの callcc 版を考えてみました。まず、Queue 相当のものなんですが、
バッファがないのでかわいらしく Hole という名前にしました。
class Hole
def open
c = nil
callcc {|c|}
if @s
true
else
@s = c
false
end
end
def post(x); callcc { |@s| @r.call(x) }; end
def get; callcc { |@r| @s.call }; end
def close
@closed = true
post nil
end
def closed?; @closed; end
end
# 使用例
h = Hole.new
if h.open
for i in 1..5
h.post i
end
h.close
end
while x = h.get
p x
end
そして ExternalIterator ですが、仕様が少し変わっています。
class ExternalIterator
def initialize(src)
@src = src
@que = Hole.new
first
end
def first
if @que.open
for i in @src
@que.post i
end
@que.close
end
end
def succ
raise 'no more items' unless success?
@que.get
end
alias next succ
def success?
not @que.closed?
end
def each()
loop do
x = succ
break unless success?
yield x
end
end
end
def match_items(a, b)
ia = ExternalIterator.new(a)
ib = ExternalIterator.new(b)
i = 0
loop do
item_a = ia.next
item_b = ib.next
if !ia.success? and ib.success?
printf "collections `a' shorter than `b'(size %d)\n", i
return
elsif ia.success? and !ib.success?
printf "collections `b' shorter than `a'(size %d)\n", i
return
elsif !ia.success? and !ib.success?
break
elsif item_a != item_b
printf "collections differ on %dth item\n", i
return
end
i+=1
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,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})
一応結果はいいみたいですが、間違ってるかも。