標籤:ruby 產生器 連續體 fibonacci
ruby中有很多經典的磁碟機結構,比如列舉程式和產生器等.這次簡單介紹下產生器的概念.產生器是按照功能要求,一次產生一個對象,或稱之為產生一個對象的方法.ruby中的連續體正好可以用來完成組建器的功能.連續體說起來晦澀,其實還是很簡單的,它有3個特點:
1. callcc方法會給代碼塊傳一個連續體對象,你可以儲存該對象;
2. 當調用連續體的call方法時指令流會跳轉到callcc方法之後;
3. 如果給連續體的call方法傳遞對象,則callcc方法會返回該對象,如果不傳遞對象,callcc會返回nil.
我們下面參考一段執行個體代碼,我加了注釋.該代碼用來產生Fibonacci數列和一個遞增數列.兩個類FibG和IncG都繼承於"抽象類別"G,G實現產生器的"抽象"事件驅動邏輯,而具體類FibG和IncG用來完成實際產生邏輯,全在代碼裡啦:
#!/usr/bin/rubyrequire 'continuation'#一個產生器"抽象"類class Gdef initializedo_gend#@main_context實際是next的"出口",讓next返回@main_context.call(v)的值,即產生的數def nextcallcc do |c|@main_context = c@g_context.callendendprivatedef do_gcallcc do |c|@g_context = creturnendg_loop#虛方法,由實際具體類實現,但由G來調用!end#@g_context實際為G的內在磁碟機,其會反覆回到g_loop中不斷產生新的數def g(v)callcc do |c|@g_context = c@main_context.call(v)endendend#具體的產生器類,用來產生Fibonacci數列class FibG < Gprivate#具體類實現g_loop,實際要怎麼產生必須由具體類說了算#g_loop不能直接由FibG的執行個體對象調用,而要通過G來驅動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(11)100.times {printf "%d " % i.next}
一個簡單的ruby產生器例子(用連續體Continuation實現)