s = "hello" puts s.enum_for(:each_char).map{|x| x.succ} #=>[i,f,m,m,p] #enum_for(function_name) 会返回一个枚举器,枚举器可以通过next来自行调用枚举的迭代 #而一般的比如array的each这些方法都会返回一个enumerator #Enumerator定义了each方法又引入了enumeratable模块,可以使用很多迭代方法 #def each # loop do # yield{self.next} # end #end enu=s.enum_for(:each_char) print enu.next
#外部迭代器来并行迭代 def sequence(*enumerables, &block) enumerables.each { |element| element.each(&block) } end
def interleave(*enumerables) enumerator = enumerables.map { |element| element.to_enum } while e = enumerator.shift begin yield e.next rescue StopIteration else enumerator << e end end end
class Fibonacc def initialize @x, @y = 0, 1 @fiber = Fiber.new do loop do @x, @y = @y, @x+@y Fiber.yield @x end end end
def next @fiber.resume end
def rewind @x,@y=0,1 end end
#可以通过纤程来创建一个有next功能的enumerator class Generate def initialize(enumerable) @enumerable = enumerable create_fiber end
def next @fiber.resume end
def rewind create_fiber end
private def create_fiber @fiber = Fiber.new do @enumerable.each do |ele| Fiber.yield ele end end end end
x=Generate.new(5..6) puts x.next
#纤程与调用纤程的进程间的参数传递 #Fiber如果初始化的时候有行参,那么第一次resume传近来的实参就是她的值 #fiber的代码快的返回值,是最后一次resume的结果 #resume的实参,就是代码块中的yield的结果 f=Fiber.new do |message| puts "Caller said #{message}" respond = Fiber.yield("Hello") puts "Caller said #{respond}" "Fine" end
respond = f.resume("Hello") puts "Fiber said #{respond}" respond = f.resume("How are you") puts "Fiber said #{respond}"
require 'continuation' class Generate def initialize load_generate end private def load_generate callcc do |c| @generator_context = c return end loop_generate end public def next callcc do |c| @main_context = c @generator_context.call end end private #它的作用就是让next可以顺序执行, #并且可以让loop_generate达到循环的目的 def generate(val) callcc do |c| @generator_context = c @main_context.call(val) end end end
class Fib < Generate def loop_generate a, b = 0, 1 loop do generate b a, b = b, a+b end end end