SoFunction
Updated on 2025-04-07

Using Continuation Continuation in Ruby to implement generator


#!/usr/bin/ruby

require 'continuation'

#A generator "abstract" class
class G
 def initialize
  do_g
 end
 
#@main_context is actually the "exit" of next, let next return the value of @main_context.call(v), that is, the generated number
 def next
  callcc do |c|
   @main_context = c
   @g_context.call
  end
 end
private
 def do_g
  callcc do |c|
   @g_context = c
   return
  end
g_loop # virtual method is implemented by the actual concrete class, but is called by G!
 end

#@g_context is actually an internal drive of G, which will repeatedly return to g_loop and continuously generate new numbers.
 def g(v)
  callcc do |c|
   @g_context = c
   @main_context.call(v)
  end
 end
end

#Specific generator class, used to generate Fibonacci sequences
class FibG < G
private
#Concrete class implements g_loop, how to generate it must be determined by the specific class
#g_loop cannot be called directly by FibG instance object, but must be driven by G.
 def g_loop
  g(1)
  a,b=1,1
  loop do
   g(b)
   a,b=b,a+b  
  end
 end
end

class IncG < G
 def initialize(inc_val=10)
  super()
  @inc_val = inc_val
 end
<span style="font-size:18px;"></span><pre name="code" class="ruby">private 
 def g_loop
  x=0
  loop do
   g(x+@inc_val)
   x+=@inc_val
  end
 end
end


f =
{printf "%d " % }
puts

i =
{printf "%d " % }
puts

i = (11)
{printf "%d " % }