挖这个,这是一个很酷的Enumerator
(惰性序列)从 1 到(最大的Float
Ruby 可以表示):
1.9.3-p327 :014 > e = (1..Float::INFINITY).each
看看我们如何抓住序列的前面:
1.9.3-p327 :015 > e.first
=> 1
1.9.3-p327 :016 > e.take(2)
=> [1, 2]
这是好东西吧?我也这么认为。但后来这个:
1.9.3-p327 :017 > e.drop(2).first
进入拉拉地。我的意思是它不会在不到 5 秒内返回。
哦,这里有一个线索:
1.9.3-p327 :020 > p e.method(:drop)
#<Method: Enumerator(Enumerable)#drop>
似乎 Enumerator ( e
) 将其#drop
方法从Enumerable
(module) 混合到Enumerator
(class) 中。现在你问为什么 Ruby 会混Enumerable
进去Enumerator
?我不知道。但是它Enumerator
在 Ruby 1.9.3和Enumerator
Ruby 2.0中都有记录。
我看到的问题是在Enumerable
工作中定义的某些方法或工作类型Enumerator
。示例包括#first
和#take
。至少还有一个:#drop
不起作用。
在我看来,Enumerator
包括Enumerable
是一个错误。你怎么看?
PS 注意到 Ruby 2.0 定义了Enumerator::Lazy
(subclass of Enumerator
),它定义了一堆Enumerable
总是惰性的方法。这里有一股腥味。为什么混合非惰性和在某些情况下损坏的方法 (into Enumerator
) 只是为了在子类 (of ) 中转身并提供惰性替代方案Enumerator
?
也可以看看:
1.9.3-p327 :018 > p e.method(:first)
#<Method: Enumerator(Enumerable)#first>
1.9.3-p327 :020 > p e.method(:drop)
#<Method: Enumerator(Enumerable)#drop>