In the Ruby Array Class documentation, I often find:
If no block is given, an enumerator is returned instead.
Why would I not pass a block to #map? What would be the use of my doing just:
[1,2,3,4].map
instead of doing:
[1,2,3,4].map{ |e| e * 10 } # => [10, 20, 30, 40]
Can someone show me a very practical example of using this enumerator?
The main distinction between an
Enumeratorand most† other data structures in the Ruby core library (Array,Hash) and standard library (Set,SortedSet) is that anEnumeratorcan be infinite. You cannot have anArrayof all even numbers or a stream of zeroes or all prime numbers, but you can definitely have such anEnumerator:So, what can you do with such an
Enumerator? Well, three things, basically.Enumeratormixes inEnumerable. Therefore, you can use allEnumerablemethods such asmap,inject,all?,any?,none?,select,rejectand so forth. Just be aware that anEnumeratormay be infinite whereasmapreturns anArray, so trying tomapan infiniteEnumeratormay create an infinitely largeArrayand take an infinite amount of time.There are wrapping methods which somehow "enrich" an
Enumeratorand return a newEnumerator. For example,Enumerator#with_indexadds a "loop counter" to the block andEnumerator#with_objectadds a memo object.You can use an
Enumeratorjust like you would use it in other languages for external iteration by using theEnumerator#nextmethod which will give you either the next value (and move theEnumeratorforward) orraiseaStopIterationexception if theEnumeratoris finite and you have reached the end.† Eg., an infinite range:
(1..1.0/0)