一个简单的ruby生成器例子(用连续体Continuation实现)
ruby中有很多经典的驱动器结构,比如枚举器和生成器等.这次简单介绍下生成器的概念.生成器是按照功能要求,一次产生一个对象,或称之为生成一个对象的方法.ruby中的连续体正好可以用来完成生成器的功能.连续体说起来晦涩,其实还是很简单的,它有3个特点:
1. callcc方法会给代码块传一个连续体对象,你可以保存该对象;
2. 当调用连续体的call方法时指令流会跳转到callcc方法之后;
3. 如果给连续体的call方法传递对象,则callcc方法会返回该对象,如果不传递对象,callcc会返回nil.
我们下面参考一段实例代码,我加了注释.该代码用来生成Fibonacci数列和一个递增数列.两个类FibG和IncG都继承于"抽象类"G,G实现生成器的"抽象"事件驱动逻辑,而具体类FibG和IncG用来完成实际生成逻辑,全在代码里啦:
#!/usr/bin/ruby
require 'continuation'
#一个生成器"抽象"类
class G
def initialize
do_g
end
#@main_context实际是next的"出口",让next返回@main_context.call(v)的值,即生成的数
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 #虚方法,由实际具体类实现,但由G来调用!
end
#@g_context实际为G的内在驱动器,其会反复回到g_loop中不断生成新的数
def g(v)
callcc do |c|
@g_context = c
@main_context.call(v)
end
end
end
#具体的生成器类,用来生成Fibonacci数列
class FibG < G
private
#具体类实现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
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 = FibG.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}
一个简单的ruby生成器例子(用连续体Continuation实现)的更多相关文章
- [Ruby on Rails系列]6、一个简单的暗语生成器与解释器(上)
[0]Ruby on Rails 系列回顾 [Ruby on Rails系列]1.开发环境准备:Vmware和Linux的安装 [Ruby on Rails系列]2.开发环境准备:Ruby on Ra ...
- Ruby学习笔记2 : 一个简单的Ruby网站,搭建ruby环境
Ruby on Rails website 的基础是 请求-返回 循环. 首先是浏览器请求服务器, 第二步,Second, in our Rails application, the route ta ...
- [转]一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程
一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程 希望此文能给初学多线程编程的朋友带来帮助,也希望牛人多多指出错误. 另外感谢以下链接的作者给予,给我的学习带来了很大帮助 http ...
- 一个简单的iBatis入门例子
一个简单的iBatis入门例子,用ORACLE和Java测试 目录结构: 1.导入iBatis和oracle驱动. 2.创建类Person.java package com.ibeats;import ...
- 2.1 一个简单的Web工程例子
一个简单的Web工程例子 开发环境: Eclipse: Neon Release (4.6.0) JDK:1.8.0_92 Tomcat:8.5.9 Maven:3.3.9 1. 在Eclipse中创 ...
- 一个简单的web服务器例子
一个简单的web容器小例子,功能十分简单,只能访问静态资源,对于新手来说还是有一定的意义.主要分三个类 1.server类:主要功能开启socketServer,阻塞server,接收socket访问 ...
- Matlab高级教程_第二篇:一个简单的混编例子
1. 常用的混编是MATLAB和VS两个编辑器之间的混编方式. 2. 因为MATLAB的核是C型语言,因此常见的混编方式是MATLAB和C型语言的混编. 3. 这里介绍一个简单的MATLAB语言混编成 ...
- 一个简单的Java程序例子以及其几种注释
在说道主题前,先来啰嗦两句,o()︿︶)o 唉,不说两句心里就有个疙瘩,也许这就是所谓的强迫症吧,好了说说我想啰嗦的,其实也就是这样子的,关于Java开发工具箱的下载以及环境的配置.Java开发工具箱 ...
- perl 一个简单的面向对象的例子
<pre name="code" class="python">[root@wx03 wx]# cat x1.pm package x1; use ...
随机推荐
- spark shuffle
Spark Shuffle 1. Shuffle相关 当Map的输出结果要被Reduce使用时,输出结果需要按key哈希,并且分发到每一个Reducer上去,这个过程就是shuffle.由于shuff ...
- SYBASE的select into与insert into使用和区别
对于表的部分或全部字段的复制,Sybase数据库提供了两种方式:select into和insert into. select into: 语法:select value1, value2, val ...
- wincvs的“License for this product has expired”问题解决
新入职的公司代码管理工具是CVS,使用wincvs作为客户端工具.今天发现执行login.logout.update等操作的时候总是报"License for this product ha ...
- 两种配置大数据环境的方法Ambari以及hadoop源代码安装的步骤
1.Ambari安装 Ambari & HDP(Hortonworks Data Platform) ********************************************* ...
- Spring中Bean多种实现切换方案
一个公共工程中的Spring配置文件,可能会被多个工程引用.因为每个工程可能只需要公共工程中的一部分Bean,所以这些工程的Spring容器启动时,需要区分开哪些Bean要创建出来.另一种场景是:想通 ...
- iOS开发之一:入门介绍
今天就介绍一下iOS开发的基本的东西,有很多东西都是经常用到的而我却经常记不住,所以还是写下来吧. iOS开发需要的开发工具是Xcode,而Xcode又必须运行在 OS X(苹果系统)环境下,所以我们 ...
- iOS中分段控制器与UIScrollView结合使用
指定根视图: // 设置window的根视图控制器 self.window.rootViewController = [[UINavigationController alloc] initWithR ...
- Linux 之归档与压缩
首先我们思考一下,归档和解压是一个概念吗?答案很明显不是啊,所谓归档,就是将一些文件归到一起,并没有对其进行压缩的操作.然而压缩则不同,见名知意.下面我们就来深入的研究一下这两个知识点吧! ----- ...
- 安装Compass时不能访问服务器的问题
今天安装Compass,居然老是提示网络问题,后来根据错误提示,发现带https的域名是访问不了的,是是SSL问题.后来搜了一下,在stackoverflow找到一个人说,将https的去掉就好了.具 ...
- C++ Primer 有感(管理类的指针成员)
C++类的指针成员与其他成员有所不同,指针成员指向一个内存地址,该地址的内存需要我没管理. 我现在分析一下为什么要管理指针成员. 有如下Student类,Student.h如下: [cpp] view ...