1.upto(2){eval('next')} 应该是不行,不知道有什么其他办法么?
yield
http://ideone.com/iZPfls
用了比较诡异的办法,自己造了作用域,但是肯定还有一些边角问题,勉强抛砖引玉吧
可以用下面的代码测试:
1.upto(10).with_control{|i| eval("Control.next if i % 2 == 0") p i }
还有一个不成熟的标签,类似 Java 的 break label,这里预想也是支持 next 和 redo 的
1.upto(10).with_control{|i| a = Control.label #获得标签,标签指向的是外层的with_control 1.upto(10).with_control{|j| Control.break a if i > 3 && j > 3 #满足条件时,连外层一起break掉 p [i, j] } }
用 fiber ?
require 'fiber' class Array def next @fiber ||= Fiber.new do each {|e| Fiber.yield(e) } nil end if @fiber && @fiber.alive? return @fiber.resume end end def restart @fiber = nil end end irb(main):206:0> arr = (1..5).to_a => [1, 2, 3, 4, 5] irb(main):207:0> arr.next => 1 irb(main):208:0> arr.next => 2 irb(main):209:0> arr.next => 3 irb(main):210:0> arr.next => 4 irb(main):211:0> arr.next => 5 irb(main):212:0> arr.next => nil
#4 楼 @gihnius 这个几乎就是 Enumerator 简化版