Ruby uses the Continuous Object Continuation implementation generator, rubycontinuation
Ruby has many classic drive structures, such as enumerators and generators. this section briefly introduces the concept of generator. A generator generates an object at a time according to functional requirements, or is called a method to generate an object. the continuous bodies in ruby can be used to complete generator functions. it is actually very simple to say that the continuous body is obscure. It has three features:
1. The callcc method will pass a continuous object to the code block. You can save this object;
2. When the call method of the continuous body is called, the command flow will jump to the callcc method;
3. If an object is passed to the call method of the continuous body, the callcc method returns this object. If no object is passed, callcc returns nil.
The following is an example code. I added a comment. this code is used to generate a Fibonacci series and an incremental series. both the fiber G and IncG classes inherit from the "abstract class" G, and G implements the "abstract" event-driven logic of the generator. The specific classes of fiber G and IncG are used to complete the actual generation logic, all in the Code:
Copy codeThe Code is as follows:
#! /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, implemented by actual classes, but called by G!
End
# @ G_context is actually an internal drive of G, and it will return to g_loop repeatedly to generate new numbers
Def g (v)
Callcc do | c |
@ G_context = c
@ Main_context.call (v)
End
End
End
# A specific generator class is used to generate a Fibonacci Series
Class FibG <G
Private
# The actual generation of a specific class to implement g_loop must be determined by the specific class.
# G_loop cannot be directly called by the fiber G 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 = fiber g. new
100. times {printf "% d" % f. next}
Puts
I = IncG. new
100. times {printf "% d" % I. next}
Puts
I = IncG. new (11)
100. times {printf "% d" % I. next}