As already mentioned, Enumerator comes in handy when you want to iterate over a sequence of data of potentially infinite length.
Take prime_generator prime generator, which extends, for example, Enumerator. If we want to get the first 5 primes, we can simply write prime_generator.take 5 instead of inserting a βlimitβ into the generating logic. Thus, we can separate the generation of primes and take a certain amount from the generated primes, which makes the generator multiple.
I for one, as a method, using Enumerable return Enumerator methods, as in the following example (it may not be a βtargetβ, but I just want to point out its aesthetic aspect):
prime_generator.take_while{|p| p < n}.each_cons(2).find_all{|pair| pair[1] - pair[0] == 2}
Here prime_generator is an instance of Enumerator that returns numbers one by one. We can take primes below n using the take_while method for Enumerable. The methods each_cons and find_all return an Enumerator so that they can be bound. This example is designed to generate double numbers below n . It may be an inefficient implementation, but it is easily written in a string and IMHO suitable for prototyping.
Here is a fairly simple implementation of prime_generator based on Enumerator:
def prime?(n) n == 2 or (n >= 3 and n.odd? and (3...n).step(2).all?{|k| n%k != 0}) end prime_generator = Enumerator.new do |yielder| n = 1 while true yielder << n if prime? n n += 1 end end
source share