How does Ruby enumerator terminate iteration? - ruby

Friends, please I need help with this explanation: In the Ruby code below, what condition termites the loop do? It's supposed to be an infinite loop, but, how does it terminate?
# Ruby code
fib = Enumerator.new do |y|
a = b = 1
loop do
y << a
a, b = b, a + b
end
end
p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
Your contributions will be highly appreciated.

(Source: https://rossta.net/blog/infinite-sequences-in-ruby.html)
The way you have implemented the function fib allows it to be "lazy." What this means, is that Ruby will not try to calculate the values in fib until it absolutely has to.
The take method on the last line is key here.
p fib.take(10)
Basically, Ruby says "I'm going to evaluate the first 10 values of fib and pretend the rest do not exist, as I don't have to use them yet."
In other words, while it is true that the fib function is potentially infinite, you only asked for the first 10 values, so you only got the first 10 values.
If you tried something like this:
p fib.to_a
Your program would get stuck. Why? Because the to_a (to array) method wants to try get all the values of fib, not just a few of them. Obviously, you cannot get all the values of an infinite list.
For more information:
https://medium.com/background-thread/what-is-lazy-evaluation-programming-word-of-the-day-8a6f4410053f
https://github.com/juinc/tilap/issues/9
--- EDIT: ---
Technical correction: As Cary Swoveland pointed out, it would be more technically correct to say that fib is an algorithm/machine that produces values on demand.

An enumerator is like a Pez® dispenser, which ejects a peppermint candy each time the top of the dispenser is pressed. An enumerator version of the dispenser would not hold a supply of candies, but would manufacture the candies one at a time, on demand, possibly being capable of producing an infinite number of them.
One type of an enumerator is tied to an underlying collection of objects. Here are two that are tied to an array.
enum = [1,2,3].each #=> #<Enumerator: [1, 2, 3]:each>
enum.next #=> 1
enum.next #=> 2
enum.next #=> 3
enum.next #=> StopIteration (iteration reached an end)
enum = [1,2,3].cycle #=> #<Enumerator: [1, 2, 3]:cycle>
enum.next #=> 1
enum.next #=> 2
enum.next #=> 3
enum.next #=> 1
enum.next #=> 2
... ad infinitum
enum.first(8)
#=> [1, 2, 3, 1, 2, 3, 1, 2]
In the first example only a finite number of objects are generated by the enumerator before a StopIteration exception is raised. In the second example an arbitrary number of objects can be generated, but only on demand. first, for example, instructs enum 8 times to generate and pass to itself one object. enum is not lazy; it is all-to-eager to comply, but will not manufacture and dispense an object until it is instructed to do so.
The other type of enumerator generates objects according to a set of rules that it was born with, rules that are not tied to an underlying object. Those enumerators are generally capable of generating an infinite number of objects. The enumerator that generates Fibonacci numbers is an example of that type of enumerator. It is not a loop that does not terminate; it is a machine that is capable of producing any number of objects, but only one at a time, on demand.

Related

Ruby code to iterate over every n-th element of an array and print it until all elements are printed?

I am asked to write some code in Ruby that iterates over every n-th element of an array and prints it until all elements of the array are printed.
The question reads:
Imagine an iterator that accesses an array in strides and runs some code at each stride. If the strides reach the end of the array then they simply begin anew from the array's beginning.
For example:
x = [0,1,2,3,4]
x.stride(1) do |elem|; puts elem; end # prints 0,1,2,3,4
x.stride(2) do |elem|; puts elem; end # prints 0,2,4,1,3
x.stride(8) do |elem|; puts elem; end # prints 0,3,1,4,2
[].stride(2) do |elem|; puts elem; end # does not print anything, but the code is correct
Assume that the stride is equal or greater than 1, and that both the stride and the array's size are not a integral/whole multiple of each other, meaning that the whole array can be printed using a given stride. Fill in the code that's missing:
class Array
def stride(step)
numelems = ... # size of the array
...
end
end
It is obvious that numelemns = self.length(). However am having trouble with the rest.
I am going to try writing some code in Python that accomplishes this task, but I am afraid that I will not be able to translate it to Ruby.
Any ideas? The answer should not be more than 4-5 lines long as the question is one that our proffessor gave us to solve in a couple of minutes.
A solution to this is provided below (thanks #user3574603):
class Array
def stride(step)
yield self[0]
(self * step).map.with_index do |element, index|
next element if index == 0
yield element if index % step == 0
end
end
end
The following assumes that arr.size and n are not both even numbers and arr.size is not a multiple of n.
def striding(arr, n)
sz = arr.size
result = '_' * sz
idx = 0
sz.times do
result[idx] = arr[idx].to_s
puts "S".rjust(idx+1)
puts result
idx = (idx + n) % sz
end
end
striding [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6], 7
S
1______________
S
1______8_______
S
1______8______6
S
1_____78______6
S
1_____78_____56
S
1____678_____56
S
1____678____456
S
1___5678____456
S
1___5678___3456
S
1__45678___3456
S
1__45678__23456
S
1_345678__23456
S
1_345678_123456
S
12345678_123456
S
123456789123456
Here is an example where arr.size is a multiple of n.
striding [1,2,3,4,5,6], 3
S
1_____
S
1__4__
S
1__4__
S
1__4__
S
1__4__
S
1__4__
Here is an example where arr.size and n are both even numbers.
striding [1,2,3,4,5,6,7,8], 6
S
1_______
S
1_____7_
S
1___5_7_
S
1_3_5_7_
S
1_3_5_7_
S
1_3_5_7_
S
1_3_5_7_
S
1_3_5_7_
Imagine an iterator that accesses an array in strides and runs some code at each stride. If the strides reach the end of the array then they simply begin anew from the array's beginning.
Based on this specification, stride will always iterate forever, unless the array is empty. But that is not a problem, since we can easily take only the amount of elements we need.
In fact, that is a good design: producing an infinite stream of values lets the consumer decide how many they need.
A simple solution could look like this:
module CoreExtensions
module EnumerableExtensions
module EnumerableWithStride
def stride(step = 1)
return enum_for(__callee__, step) unless block_given?
enum = cycle
loop do
yield(enum.next)
(step - 1).times { enum.next }
end
self
end
end
end
end
Enumerable.include(CoreExtensions::EnumerableExtensions::EnumerableWithStride)
A couple of things to note here:
I chose to add the stride method to Enumerable instead of Array. Enumerable is Ruby's work horse for iteration and there is nothing in the stride method that requires self to be an Array. Enumerable is simply the better place for it.
Instead of directly monkey-patching Enumerable, I put the method in a separate module. That makes it easier to debug code for others. If they see a stride method they don't recognize, and inspect the inheritance chain of the object, they will immediately see a module named EnumerableWithStride in the inheritance chain and can make the reasonable assumption that the method is probably coming from here:
[].stride
# Huh, what is this `stride` method? I have never seen it before.
# And it is not documented on https://ruby-doc.org/
# Let's investigate:
[].class.ancestors
#=> [
# Array,
# Enumerable,
# CoreExtensions::EnumerableExtensions::EnumerableWithStride,
# Object,
# Kernel,
# BasicObject
# ]
# So, we're confused about a method named `stride` and we
# found a module whose name includes `Stride`.
# We can reasonably guess that somewhere in the system,
# there must be a file named
# `core_extensions/enumerable_extensions/enumerable_with_stride.rb`.
# Or, we could ask the method directly:
meth = [].method(:stride)
meth.owner
#=> CoreExtensions::EnumerableExtensions::EnumerableWithStride
meth.source_location
#=> [
# 'core_extensions/enumerable_extensions/enumerable_with_stride.rb',
# 6
# ]
For an empty array, nothing happens:
[].stride(2, &method(:p))
#=> []
stride just returns self (just like each does) and the block is never executed.
For a non-empty array, we get an infinite stream of values:
x.stride(&method(:p))
# 0
# 1
# 2
# 3
# 4
# 0
# 1
# …
x.stride(2, &method(:p))
# 0
# 2
# 4
# 1
# 3
# 0
# 2
# …
x.stride(8, &method(:p))
# 0
# 3
# 1
# 4
# 2
# 0
# 3
# …
The nice thing about this infinite stream of values is that we, as the consumer can freely choose how many elements we want. For example, if I want 10 elements, I simply take 10 elements:
x.stride(3).take(10)
#=> [0, 3, 1, 4, 2, 0, 3, 1, 4, 2]
This works because, like all well-behaved iterators, our stride method returns an Enumerator in case no block is supplied:
enum = x.stride(2)
#=> #<Enumerator: ...>
enum.next
#=> 0
enum.next
#=> 2
enum.next
#=> 4
enum.next
#=> 1
enum.next
#=> 3
enum.next
#=> 0
enum.next
#=> 2
So, if we want to implement the requirement "until all the elements of the array are printed":
I am asked to write some code in Ruby that iterates over every n-th element of an array and prints it until all elements of the array are printed.
We could implement that something like this:
x.stride.take(x.length).each(&method(:p))
x.stride(2).take(x.length).each(&method(:p))
x.stride(8).take(x.length).each(&method(:p))
This is a pretty simplistic implementation, though. Here, we simply print as many elements as there are elements in the original array.
We could implement a more sophisticated logic using Enumerable#take_while that keeps track of which elements have been printed and which haven't, and only stops if all elements are printed. But we can easily prove that after x.length iterations either all elements have been printed or there will never be all elements printed (if the stride size is an integral multiple of the array length or vice versa). So, this should be fine.
This almost does what I think you want but breaks if the step is array.length + 1 array.length (but you mention that we should assume the stride is not a multiply of the array length).
class Array
def exhaustive_stride(step)
(self * step).map.with_index do |element, index|
next element if index == 0
element if index % step == 0
end.compact
end
end
x.exhaustive_stride 1
#=> [0, 1, 2, 3, 4]
x.exhaustive_stride 2
#=> [0, 2, 4, 1, 3]
x.exhaustive_stride 8
#=> [0, 3, 1, 4, 2]
[].exhaustive_stride 2
#=> []
Using the example array, it breaks when the stride is 5.
[0,1,2,3,4].exhaustive_stride 5
#=> [0, 0, 0, 0, 0]
Note
This works but the intermediate array makes it highly inefficient. Consider other answers.
Here's another solution that uses recursion. Not the most efficient but one way of doing it.
class Array
def exhaustive_stride(x, r = [])
return [] if self.empty?
r << self[0] if r.empty?
while x > self.length
x -= self.length
end
r << self[x]
x += x
return r if r.count == self.count
stride(x, r)
end
end
[0,1,2,3,4].exhaustive_stride 1
#=> [0, 1, 2, 4, 3]
[0,1,2,3,4].exhaustive_stride 2
#=> [0, 2, 4, 3, 1]
[0,1,2,3,4].exhaustive_stride 8
#=> [0, 3, 1, 2, 4]
[].exhaustive_stride 2
#=> []
[0,1,2,3,4].exhaustive_stride 100_000_001
#=> [0, 1, 2, 4, 3]
This would work:
def stride(ary, step)
raise ArgumentError unless step.gcd(ary.size) == 1
Array.new(ary.size) { |i| ary[(i * step) % ary.size] }
end
Example:
x = [0, 1, 2, 3, 4]
stride(x, 1) #=> [0, 1, 2, 3, 4]
stride(x, 2) #=> [0, 2, 4, 1, 3]
stride(x, 8) #=> [0, 3, 1, 4, 2]
stride(x, -1) #=> [0, 4, 3, 2, 1]
First of all, the guard clause checks whether step and ary.size are coprime to ensure that all elements can be visited via step.
Array.new(ary.size) creates a new array of the same size as the original array. The elements are then retrieved from the original array by multiplying the element's index by step and then performing a modulo operation using the array's size.
Having % arr.size is equivalent to fetching the elements from a cyclic array, e.g. for a step value of 2:
0 1 2 3 4
| | | | |
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, ...
To turn this into an instance method for Array you merely replace ary with self (which can be omitted most of the time):
class Array
def stride(step)
raise ArgumentError unless step.gcd(size) == 1
Array.new(size) { |i| self[(i * step) % size] }
end
end

Why is uniq needed in this problem? (Ruby)

New to coding, and trying to study independently. Working on a problem on Ruby, where we create a method (filter_out!) that mutates the original array to remove true elements when the array is passed through a proc. The only stipulation is that we aren't allowed to use Array#reject!.
Can anyone explain to me why
arr.uniq.each { |ele| arr.delete(ele) if prc.call(ele)}
works and
arr.each { |ele| arr.delete(ele) if prc.call(ele)}
does not? Here are two example problems:
arr_2 = [1, 7, 3, 5 ]
filter_out!(arr_2) { |x| x.odd? }
p arr_2 # []
arr_3 = [10, 6, 3, 2, 5 ]
filter_out!(arr_3) { |x| x.even? }
p arr_3 # [3, 5]
I've looked it up and understand #uniq removes duplicate values, right?
Any insight would be greatly appreciated-thank you!
edit: Looked into it more, is it because uniq will use the return value of the proc for comparison? Still not sure why this is needed for some numbers, but not all.
The only stipulation is that we aren't allowed to use Array#reject!.
This is an incredibly braindead stipulation. You could just use Array#select! and invert the condition, or use Array#reject together with Array#replace, for example.
Can anyone explain to me why
arr.uniq.each { |ele| arr.delete(ele) if prc.call(ele)}
works and
arr.each { |ele| arr.delete(ele) if prc.call(ele)}
Whenever you don't quite understand what a piece of code does, a good idea is to just run it yourself with a pen and a piece of paper.
So, let's just do that. Assume arr = [1, 2, 4, 5, 2] and prc = -> e { e.even? }.
Array#each iterates through the array, we don't exactly know how it does it (that is the whole idea of abstraction), but we can imagine that it keeps some kind of index to remember which part of the array it is currently at.
So, during the first iteration of the array, the index is at the first element, and the array looks like this:
[1, 2, 4, 5, 2]
# ↑
Array#each passes 1 to the block, which in turn passes it to prc, which returns false, thus the block doesn't do anything.
Array#each increases the index, so now our array looks like this:
[1, 2, 4, 5, 2]
# ↑
Array#each passes 2 to the block, which in turn passes it to prc, which returns true. As a result, the block now passes 2 to Array#delete, which deletes every element from the array that is equal to 2. So, now the array looks like this:
[1, 4, 5]
# ↑
Array#each increases the index, so now our array looks like this:
[1, 4, 5]
# ↑
Array#each passes 5 to the block, which in turn passes it to prc, which returns false, thus the block doesn't do anything.
Array#each increases the index, so now our array looks like this:
[1, 4, 5]
# ↑
Since index is past the end of the array, the iteration is done, and the result is [1, 4, 5].
As you can see, the problem is that you are mutating the array while iterating over it.
I've looked it up and understand #uniq removes duplicate values, right?
Correct, but that has nothing to do with why it makes your code work. Or, more precisely, makes it seem to work because there are actually a lot of other problems with your code as well.
It is not the fact that Array#uniq removes duplicate values that is relevant, it is the fact that Array#uniq returns a new array. Since Array#uniq returns a new array, you are no longer mutating an array while iterating over it, you are mutating one array while iterating over another.
You could have used any method of Array or one of its ancestors that returns a new array, for example Object#clone, Object#dup, Array#map, or Array#select, or even something really creative such as arr + []:
arr.select { true }.each {|ele| arr.delete(ele) if prc.call(ele) }
In fact, you don't even need to return an Array, you only need to return some kind of Enumerable, such as an Enumerator, for example using Array#each:
arr.each.each {|ele| arr.delete(ele) if prc.call(ele) }
edit: Looked into it more, is it because uniq will use the return value of the proc for comparison? Still not sure why this is needed for some numbers, but not all.
Since you are not passing the proc to Array#uniq, it cannot possibly use it for anything, so it is clearly impossible for this to be the explanation.
Note that, as I explained above, there are more problems with your code than just mutating an array while iterating over it.
Even if your original code did work, it would actually still be broken. You are using Array#delete to delete the element for which prc returns true. The problem is that Array#delete deletes all elements in the array that are #== to the element you are passing as an argument, even the ones for which the prc might return false.
Here is a trivial example:
a = [2, 2, 2]
i = -1
filter_out!(a) { (i += 1) == 1 }
This should only filter out the second element, but actually deletes all of them, so the result is [] when it actually should be [2, 2].
Your version with Array#uniq makes this problem even worse, because after running Array#uniq, the array doesn't even have a second element any more! So, the result is [2], when it actually should be [2, 2].
The next problem is the name of the method: filter_out!. Bang methods (i.e. methods whose name ends with an exclamation mark !) are used to mark the more surprising method of a pair of methods. You should never have a bang method on its own. The name filter_out! should only be used if and only if there is also a filter_out method. So, the method should be named filter_out.
And the last problem is that you are mutating the argument that is passed into the method. That is an absolute no-no. You never, ever mutate an argument that is passed into a method. Never. You never break somebody else's toys, you never touch somebody else's privates.
Mutation, in general, should be avoided as much as possible, since it can lead to confusing and hard to track down bugs, as you so beautifully have discovered yourself. Only if absolutely necessary should you mutate state, and only state that you yourself own. Never mutate somebody else's state. Instead, filter_out should return a new array with the results.
Here are a couple of examples what filter_out could look like:
def filter_out(enum)
enum.select {|el| !yield el }
end
def filter_out(enum)
enum.reduce([]) {|acc, el| if yield el then acc else acc + [el] end }
end
def filter_out(enum)
enum.each_with_object([]) {|el, acc| acc << el unless yield el }
end
Note: Personally, I am not a big fan of Enumerable#each_with_object, because it relies on mutation, so I would avoid that solution as much as possible.
However, the real problem seems to be that whatever course or book or tutorial or class you are following seems to be pretty terrible, both a teaching Ruby, and at teaching good Software Engineering practices, such as testing and debugging.
The behaviour you have witnessed has nothing to do with the fact that a proc is present. The problem is that you are invoking a method (Array#each) on a receiver (the array) that is altered (mutated) in the method's block.
Suppose:
arr = [true, false, true]
arr.each do |x| puts "x = #{x}, arr = #{arr}"
arr.delete(x)
puts "arr = #{arr}"
end
#=> [false]
The following is printed:
x = true, arr = [true, false, true]
arr = [false]
You were perhaps expecting to see an empty array returned, not [false].
As you see from the printed output, only arr[0] #=> true was passed to each's block. That caused arr.delete(x) to delete both instances of true from arr, causing arr to then equal [false]. Ruby then attempts to pass arr[1] to the block but finds that arr has only one element so she concludes she is finished and returns arr #=> [false].
Had arr = [true, true, true] the return value (an empty array) would be correct, but only because all elements are removed when the first element of arr is passed to the block. This is analogous to the example in the question of removing all odd elements of [1, 7, 3, 5].
Even when the code is technically correct it is considered bad practice to invoke a method on a receiver that alters the receiver in its block.
If we first invoke uniq we are no longer iterating over the array we are modifying, so all is well:
a = arr.uniq
#=> [true, false]
a.each do |x| puts "x = #{x}, arr = #{arr}"
arr.delete(x)
puts "arr = #{arr}"
end
#=> [true, false]
The following is printed:
x = true, arr = [true, false, true]
arr = [false]
x = false, arr = [false]
arr = []
Similarly,
a = arr.dup
#=> [true, false]
a.each do |x| puts "x = #{x}, arr = #{arr}"
arr.delete(x)
puts "arr = #{arr}"
end
#=> [true, false, true]
The following is printed:
x = true, arr = [true, false, true]
arr = [false]
x = false, arr = [false]
arr = []
x = true, arr = []
arr = []

How does to_enum(:method) receive its block here?

This code, from an example I found, counts the number of elements in the array which are equal to their index. But how ?
[4, 1, 2, 0].to_enum(:count).each_with_index{|elem, index| elem == index}
I could not have done it only with chaining, and the order of evaluation within the chain is confusing.
What I understand is we're using the overload of Enumerable#count which, if a block is given, counts the number of elements yielding a true value. I see that each_with_index has the logic for whether the item is equal to it's index.
What I don't understand is how each_with_index becomes the block argument of count, or why the each_with_index works as though it was called directly on [4,1,2,0]. If map_with_index existed, I could have done:
[4,1,2,0].map_with_index{ |e,i| e==i ? e : nil}.compact
but help me understand this enumerable-based style please - it's elegant!
Let's start with a simpler example:
[4, 1, 2, 0].count{|elem| elem == 4}
=> 1
So here the count method returns 1 since the block returns true for one element of the array (the first one).
Now let's look at your code. First, Ruby creates an enumerator object when we call to_enum:
[4, 1, 2, 0].to_enum(:count)
=> #<Enumerator: [4, 1, 2, 0]:count>
Here the enumerator is waiting to execute the iteration, using the [4, 1, 2, 0] array and the count method. Enumerators are like a pending iteration, waiting to happen later.
Next, you call the each_with_index method on the enumerator, and provide a block:
...each_with_index{|elem, index| elem == index}
This calls the Enumerator#each_with_index method on the enumerator object you created above. What Enumerator#each_with_index does is start the pending iteration, using the given block. But it also passes an index value to the block, along with the values from the iteration. Since the pending iteration was setup to use the count method, the enumerator will call Array#count. This passes each element from the array back to the enumerator, which passes them into the block along with the index. Finally, Array#count counts up the true values, just like with the simpler example above.
For me the key to understanding this is that you're using the Enumerator#each_with_index method.
The answer is but a click away: the documentation for Enumerator:
Most [Enumerator] methods [but presumably also Kernel#to_enum and Kernel#enum_for] have two forms: a block form where the contents are evaluated for each item in the enumeration, and a non-block form which returns a new Enumerator wrapping the iteration.
It is the second that applies here:
enum = [4, 1, 2, 0].to_enum(:count) # => #<Enumerator: [4, 1, 2, 0]:count>
enum.class # => Enumerator
enum_ewi = enum.each_with_index
# => #<Enumerator: #<Enumerator: [4, 1, 2, 0]:count>:each_with_index>
enum_ewi.class # => Enumerator
enum_ewi.each {|elem, index| elem == index} # => 2
Note in particular irb's return from the third line. It goes on say, "This allows you to chain Enumerators together." and gives map.with_index as an example.
Why stop here?
enum_ewi == enum_ewi.each.each.each # => true
yet_another = enum_ewi.each_with_index
# => #<Enumerator: #<Enumerator: #<Enumerator: [4, 1, 2, 0]:count>:each_with_index>:each_with_index>
yet_another.each_with_index {|e,i| puts "e = #{e}, i = #{i}"}
e = [4, 0], i = 0
e = [1, 1], i = 1
e = [2, 2], i = 2
e = [0, 3], i = 3
yet_another.each_with_index {|e,i| e.first.first == i} # => 2
(Edit 1: replaced example from docs with one pertinent to the question. Edit 2: added "Why stop here?)
Nice answer #Cary.. I'm not exactly sure how the block makes its way through the chain of objects, but despite appearances, the block is being executed by the count method, as in this stack trace, even though its variables are bound to those yielded by each_with_index
enum = [4, 1, 2, 0].to_enum(:count)
enum.each_with_index{|e,i| raise "--" if i==3; puts e; e == i}
4
1
2
RuntimeError: --
from (irb):243:in `block in irb_binding'
from (irb):243:in `count'
from (irb):243:in `each_with_index'
from (irb):243

Enumerators in Ruby

I'm having a trouble understanding Enumerators in Ruby.
Please correct me If I'm wrong, o.enum_for(:arg) method is supposed to convert object to Enumerator and every iteration over object o should call arg method?
What confuses me is how this line of code works
[4, 1, 2, 0].enum_for(:count).each_with_index do |elem, index|
elem == index
end
It should count how many elements are equal to their position in the array, and it works. However, I don't understand what's actually going on. Is each_with_index calling count method on every iteration? If someone could explain, it would be great.
From Programming Ruby:
count enum.count {| obj | block } → int
Returns the count of objects in enum that equal obj or for which the
block returns a true value.
So the enumerator visits each element and adds 1 to the count if the block returns true, which in this case means if the element is equal to the array index.
I haven't seen this pattern used much (if at all)—I would be more inclined to:
[4, 1, 2, 0].each_with_index.select { |elem, index| elem == index }.count
EDIT
Lets take a look at the example from your comment:
[4, 1, 2, 0].enum_for(:each_slice, 2).map do |a, b|
a + b
end
each_slice(2) takes the array 2 elements at a time and returns an array for each slice:
[4, 1, 2, 0].each_slice(2).map # => [[4,1], [2,0]]
calling map on the result lets us operate on each sub-array, passing it into a block:
[4, 1, 2, 0].enum_for(:each_slice, 2).map do |a,b|
puts "#{a.inspect} #{b.inspect}"
end
results in
4 1
2 0
a and b get their values by virtue of the block arguments being "splatted":
a, b = *[4, 1]
a # => 4
b # => 1
You could also take the array slice as the argument instead:
[4, 1, 2, 0].enum_for(:each_slice, 2).map {|a| puts "#{a.inspect}"}
[4, 1]
[2, 0]
Which lets you do this:
[4, 1, 2, 0].enum_for(:each_slice, 2).map {|a| a.inject(:+) } #=> [5,2]
Or if you have ActiveSupport (i.e. a Rails app),
[4, 1, 2, 0].enum_for(:each_slice, 2).map {|a| a.sum }
Which seems a lot clearer to me than the original example.
array.count can normally take a block, but on its own, it returns a fixnum, so it can't be chained to .with_index the way some other iterators can (try array.map.with_index {|x,i ... }, etc).
.enum_for(:count) converts it into a enumerator, which allows that chaining to take place. It iterates once over the members of array, and keeps a tally of how many of them equal their indexes. So count is really only being called once, but only after converting the array into something more flexible.

Difference Between map and each [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Ruby - What is the difference between map, each and collect?
I have looked in Ruby-Doc also but i cant understand the difference between
map
each
iterators.It would be great if you could give an example and explain.
each simply iterates over the given enumerable, running the block for each value. It discards the return value of the block, and each simply returns the original object it was called on:
[1, 2, 3].each do |x|
x + 1
end # => [1, 2, 3]
This is simply a nicer, more universal way of doing a traditional iterating for loop, and each is much preferred over for loops in Ruby (in fact, I don't think I've ever used a for loop in Ruby).
map, however, iterates over each element, using the return value of the block to populate a new array at each respective index and return that new array:
[1, 2, 3].map do |x|
x + 1
end # => [2, 3, 4]
So it “maps” each element to a new one using the block given, hence the name “map”. Note that neither each nor map themselves modify the original collection. This is a concise, functional alternative to creating an array and pushing to it in an iterative loop.
each returns the original object. It's used to run an operation using each element of an array without collecting any of the results. For example, if you want to print a list of numbers, you might do something like this:
arr = [1, 2, 3, 4]
arr.each { |n| puts n }
Now, that puts method above actually returns nil. Some people don't know that, but it doesn't matter much anyway; there's no real reason to collect that value (if you wanted to convert arr to strings, you should be using arr.map(&:to_s) or arr.map { |n| n.to_s }.
map returns the results of the block you pass to it. It's a great way to run an operation on each element in an array and retrieve the results. If you wanted to multiple every element of an array by 2, this is the natural choice. As a bonus, you can modify the original object using map!. For example:
arr = [1, 2, 3, 4]
arr.map! { |n| n * 2}
# => [2, 4, 6, 8]

Resources