There are a number of classic drive architectures in Ruby, such as enumerators and generators. This is a simple introduction to the concept of generators. The generator is a function requirement that produces an object at a time, or a method that generates an object. The continuum in Ruby can be used to complete the function of the generator. The continuum speaks of obscurity, In fact it is very simple, it has 3 features:
1. The CALLCC method will pass a continuum object to the code block, and you can save the object;
2. When the call method of the continuum is called, the instruction flow jumps to the CALLCC method;
3. If the object is passed to the call method of the continuum, the CALLCC method returns the object, and if the object is not passed, CALLCC returns nil.
We refer to the following example code, I added a comment. The code is used to generate the Fibonacci sequence and an increment sequence. The two classes FIBG and INCG inherit from the abstract class g,g implement the "abstract" event-driven logic of the generator, and the concrete classes FIBG and INCG are used to complete the actual generation logic, It's all in the code:
#!/usr/bin/rubyrequire ' continuation ' #一个生成器 "abstract" class Gdef initializedo_gend# @main_context is actually the "exit" of Next, Let next return the value of @main_context.call (v), which is the generated number def NEXTCALLCC do |c| @main_context = C@g_context.callendendprivatedef DO_GCALLCC Do |c| @g_context = creturnendg_loop# virtual method, implemented by the actual concrete class, but by the G to call the!end# @g_context the actual g of the intrinsic drive, which will be repeated back to the G_loop constantly generate new number Def g (v) CALLCC do |c| @g_context = C@main_context.call (v) endendend# Concrete generator class, used to generate Fibonacci sequence class FIBG < gprivate# concrete class implementation G_loop , how the actual build must be determined by the specific class #g_loop cannot be called directly by the FIBG instance object, but through G to drive the Def G_LOOPG (1) a,b=1,1loop Dog (b) A,b=b,a+bendendendclass INCG < Gdef Initialize (inc_val=10) super () @inc_val = Inc_valend<span style= "FONT-SIZE:18PX;" ></span><pre name= "code" class= "Ruby" >privatedef g_loopx=0loop Dog (email protected]_val) [email PROTECTED]_VALENDENDENDF = FibG.new100.times {printf "%d"% F.next}putsi = IncG.new100.times {printf "%d"% i.next}puts i = incg.new (one) 100.times {printf "%d"% I.next}
A simple Ruby Generator example (implemented with continuum continuation)