--J2pR2RtFp0tAjF3C Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Ben Giddings (ben / thingmagic.com) wrote: > On Wed August 6 2003 6:45 pm, Dan Sugalski wrote: > > >1) Why do they have the strange syntax they have > > > > They don't--there's no inherent strange syntax to them. The syntax > > comes from the language implementing the continuation semantics. > > Like Hal said, I meant why do they have the strange syntax they do "in Ruby". > There just doesn't seem to be a good reason for a block. It also seems > strange to have a class with no constructor that can only be created by a > Kernel method. The advantage to the block is that it allows you to do some stuff with the continuation (like saving this potential chain of execution) without continuaing. Not having the block makes things much more difficult. Take a look at the guts of Borges, particuarly Session.rb. http://segment7.net/ruby-code/borges/borges.html If you read below, you'll see the continuation captures what you're doing in respond, and saves it, and doesn't return until you invoke that continuation. The block allows you to do some stuff, *then* invoke, but only if you really want to in the convenient ruby metaphor. You may have to read more of the code to really understand what's going on here, I only understand enough of it to have an intuitive feel for the deep magic that's going on inside. I couldn't rewrite it from scratch. class Session # ... def handle_request_intern(request, response) @response = response @current_key = request.action_key callcc do |cc| @short_jmp = cc # *** note this if cont = @continuations[@current_key] # if there is a continuation for current_key, invoke cont.call(request) else # handle unknown requests unknown_request(request) end end @last_key = @current_key end # ... def respond callcc do |cc| @response.action_key = @continuations.store(cc) yield(@response) @short_jmp.call # *** is used here end end end And this code gets used in Renderer.rb: def render_response @callbacks = CallbackStore.new request = respond do |res| @response = @stream = res yield(self) end @callbacks.process_callbacks(request) end def text_input(value, attrs={}, &update) attrs["value"] = value # This only gets invoked if this action is chosen. attrs["name"] = @callbacks.register_callback(update) input("text", attrs) end > Is there some reason that Continuation.new couldn't work? I don't know if this is 100% correct: class Continuation def self.new if block_given? then callcc { |c| yield(c) } else callcc { |c| return c } end end end -- Eric Hodel - drbrain / segment7.net - http://segment7.net All messages signed with fingerprint: FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04 --J2pR2RtFp0tAjF3C Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.2 (FreeBSD) iD8DBQE/MZJ4MypVHHlsnwQRAqDqAKCUF+D2Vtm8aZ5xpsAxq4/Xfyt9HwCfdNgY KmDMkK1c+XXDc/nfNCgEJw8MR -----END PGP SIGNATURE----- --J2pR2RtFp0tAjF3C--