to_enum方法
to_enum是Object类的实例方法,有以下两种调用方式(可参考ruby api文档):
obj.to_enum(method = :each, *args) → enum
obj.to_enum(method = :each, *args) {|*args| block} → enum
to_enum会返回一个Enumerator,其内部的迭代方法就是调用这个method,默认method是each。
示例:
[18] pry(main)> class B
[18] pry(main)* def iter(&block)
[18] pry(main)* pp :abcdefg
[18] pry(main)* return to_enum unless block
[18] pry(main)* (6..12).each(&block)
[18] pry(main)* end
[18] pry(main)* end
=> :iter
[19] pry(main)> B.new.to_enum
=> #<enumerator: ...="">
[20] pry(main)> B.new.to_enum.map{ |e| e + 1 }
NoMethodError: undefined method `each' for #
from (pry):38:in `each'
[21] pry(main)> B.new.to_enum(:iter).map{ |e| e + 1 }
:abcdefg
=> [7, 8, 9, 10, 11, 12, 13]
[22] pry(main)> B.new.to_enum(:iter).to_a
:abcdefg
=> [6, 7, 8, 9, 10, 11, 12] </enumerator:>
顺提,在Enumerator对象上调用to_a,可以认为是:
arr = []
enum.each{ |e| arr << e }
return arr
调用to_enum时带block,则会在调用Enumerator#size时直接使用block的运行结果,而非迭代计数
[16] pry(main)> en = [1,2,3].to_enum{2}
=> #<enumerator: ...="">
[17] pry(main)> en.size
=> 2</enumerator:>