to_enum 这个方法,ruby文档中描述它产生一个Enumerator对象。如果没有一个块,通常直接返回一个Enumerator对象。如果提供了一个块,它默认绑定遍历方法是:each,你也可以指定其他方法。
\
class Abc include Enumerable def initialize() @arr = [1, 3, 5, 7] @index = 0 end def each2(*args) puts "进入each2" p args 3.times do |i| yield i end end # 事实上,each其实只执行一次, # 具体的遍历是由each内部的实现 # 来决定的 def each(*args) if ! block_given? # 这里将:each2绑定到enumerable上 # ,调用each方法将实际调用:each2 # 如果提供一个块,这个块用来计算迭代的大小 # 即调用Enumerator#size来执行这个块 return to_enum(:each2, *args) { puts "to_enum"; size(); } else puts "进入each" while @index < @arr.length yield @arr[@index] @index += 1 end self end end # def each .. end def size end end a = Abc.new e = a.each("java") x = e.each do |i| p i end p e.inspect p e.size