挖這一點,這裏是一個很酷的Enumerator
(懶惰序列)從1到(最大Float
紅寶石可以代表):爲什麼枚舉包括可枚舉
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
進入lala土地。我的意思是,它不會在不到5秒的時間內返回。這裏
哦,是一個線索:
1.9.3-p327 :020 > p e.method(:drop)
#<Method: Enumerator(Enumerable)#drop>
看來,枚舉(e
)得到它從Enumerable
(模塊)#drop
方法到Enumerator
(類)混合。現在爲什麼在世界上Ruby會去Enumerable
到Enumerator
你問?我不知道。但在那裏,記錄在Enumerator
in Ruby 1.9.3和Enumerator
in Ruby 2.0。
我看到的問題是Enumerable
中定義的一些方法在Enumerator
上的工作或種類。示例包括#first
和#take
。至少有一個:#drop
不起作用。
在我看來,Enumerator
包括Enumerable
是一個錯誤。你怎麼看?請注意,Ruby 2.0定義了Enumerator::Lazy
(Enumerator
的子類),它定義了一堆非常懶惰的Enumerable
方法。有東西在這裏聞起來有些腥臭。爲什麼混入非懶惰的方法和某些情況下破壞的方法(到Enumerator
)只能在子類中(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>
請注意,'e =(1..Float :: INFINITY).each'中的'each'沒有區別。你應該放棄它,或者用「懶惰」來取代它,這取決於你想要的東西。 – 2013-04-11 01:14:52
謝謝Marc-André。但是Ruby 1.9.3中沒有Enumerable#懶。這僅在2.0版本中可用。我認爲我的一個主要誤解是假設#drop完全返回了一個Enumerator。出於某種原因,雖然#drop和#take都有可能的微不足道的枚舉器實現,但它們都不會返回枚舉器!即使修復了[Ruby Bug#7715「懶惰枚舉員應該保持懶惰」](https://bugs.ruby-lang.org/issues/7715)也無法解決這些問題。想想看,這些不能「固定」,因爲這樣做會破壞依賴於返回數組的代碼! – 2013-04-11 04:52:55
的確,「drop」是「渴望」的。順便說一句,你可以在'require'backports/2.0.0/enumerable/lazy''的任何版本的Ruby中使用'lazy'' – 2013-04-11 06:42:39