[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Coroutines (Was: FasterGenerator (#66

Ross Bamford

2/16/2006 11:23:00 AM

Hi,

Well, I've snapped a string on my guitar and my computer won't play MP3s
today for some reason, so inevitably boredom started to creep in. I
started playing around with the generator stuff, specifically about the
coroutine discussion earlier in this thread. Just wanted to see if I
could *really* get my head around continuations and all that.

It starts with some private methods on Kernel, which are then used to
implement the generator, but can be used elsewhere too:

module Kernel
private
def coreset(blk)
Thread.current[:"#{blk.inspect.hash}_codone"] = nil
end

def coyield?(blk)
Thread.current[:"#{blk.inspect.hash}_codone"] ? false : true
end

def coyield(blk, *args)
raise "Coroutine exhausted" if Thread.current[:"#{blk.inspect.hash}_codone"]

catch :coreturn do
next_item = (Thread.current[:coreturn] ||= []).pop

if next_item
next_item.call
else
final = blk.call(*args)
Thread.current[:"#{blk.inspect.hash}_codone"] = true
throw :coreturn, final
end
end
end

def coreturn(val)
callcc do |return_cc|
(Thread.current[:coreturn] ||= []) << return_cc
throw :coreturn, val
end
end
end

class CoGenerator
def initialize(enum = nil, &blk)
@blk, @pos = blk, 0

if enum
@blk = lambda { enum.each { |e| coreturn e } }
end
end

def rewind
@pos = 0
coreset @blk
end

def next
@pos += 1
@current = coyield(@blk)
end

def current
@current
end

def next?
coyield? @blk
end

def end?
!self.next?
end

def each
rewind
yield coyield(@blk) while coyield?(@blk)
end

def pos
@pos
end
end

It would be used like:

g = CoGenerator.new do
coreturn 6
# Some work
coreturn 7
# More work
coreturn 8
# Yet more work
9
end

p g.next while g.next?
# ->
# 6
# 7
# 8
# 9

Obviously this isn't for the quiz (it'd be dead last, being based on
continuations, and it doesn't actually have the Generator API) but just,
well, for fun. And something to do. It was fun to write, but it's a toy.
I dread to think what it mightn't do properly, or at all :) It's
behaviour in multithreaded code could well be a bit counter-intuitive
too, I'm afraid I don't know much about how coroutines work in other
languages.

It times a bit faster than the old callcc generator, because it's using
less continuations (just the one) but really I guess it's just a test of
the coyield/coreturn stuff.

Anyway, enough about that... Music shop will be open now :)

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk



1 Answer

Jim Weirich

2/16/2006 1:53:00 PM

0

Ross Bamford wrote:
> Hi,
>
> Well, I've snapped a string on my guitar and my computer won't play MP3s
> today for some reason,

I've come to believe that having a backup set of guitar strings is
nearly as important as having a backup for your hard disk.

--
-- Jim Weirich

--
Posted via http://www.ruby-....