`call/cc’ and Self-modifying Code, in Ruby

If you read Matthias Felleisen’s blog post today about using call/cc to write a generator, and you’re anything like me, you must have thought “Ruby has call/cc; how would I do this in Ruby?”

This is my first pass. It works, but it could very well be broken, and I know it can have a better interface.

class Array
  def generate_one_element_at_a_time
    control_state = Proc.new do |ret|
      each do |an_element_from_a_list|
        callcc do |resume_here|
          control_state = Proc.new do |r|
            resume_here.call(r)
          end
          ret.call(an_element_from_a_list)
        end
      end
      ret.call(:you_fell_off_the_end_of_the_list)
    end
    Proc.new { callcc {|k| control_state.call(k)} }
  end
end

It is used like this:

irb(main):001:0> a = %w(a b c).generate_one_element_at_a_time
=> #
irb(main):002:0> a.call
=> "a"
irb(main):003:0> a.call
=> "b"
irb(main):004:0> a.call
=> "c"
irb(main):005:0> a.call
=> :you_fell_off_the_end_of_the_list
irb(main):006:0> a.call
=> :you_fell_off_the_end_of_the_list
Advertisements
%d bloggers like this: