当前位置: 代码迷 >> Ruby/Rails >> 一个容易的ruby生成器例子(用连续体Continuation实现)
  详细解决方案

一个容易的ruby生成器例子(用连续体Continuation实现)

热度:138   发布时间:2016-04-29 02:18:38.0
一个简单的ruby生成器例子(用连续体Continuation实现)

    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 G	def initialize		do_g	end		[email protected]_context实际是next的"出口",[email protected]_context.call(v)的值,即生成的数	def next		callcc do |c|			@main_context = c			@g_context.call		end	endprivate	def do_g		callcc do |c|			@g_context = c			return		end		g_loop	#虚方法,由实际具体类实现,但由G来调用!	end	[email protected]_context实际为G的内在驱动器,其会反复回到g_loop中不断生成新的数	def g(v)		callcc do |c|			@g_context = c			@main_context.call(v)		end	endend#具体的生成器类,用来生成Fibonacci数列class FibG < Gprivate	#具体类实现g_loop,实际要怎么生成必须由具体类说了算	#g_loop不能直接由FibG的实例对象调用,而要通过G来驱动	def g_loop		g(1)		a,b=1,1		loop do			g(b)			a,b=b,a+b				end	endendclass 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([email protected]_val)			[email protected]_val		end	endendf = 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}