Reputation: 91
I am doing an exercise with Ruby blocks and procs and I have been stuck for a few hours now . In the exercise I first had to create a my_each method that would receive a proc and would emulate the behaviour of the each method without using each. It would then return the original array unchanged. We are then asked to create a method that would emulate the map method (without using map) by using the my_each method already created. In the solutions we were given the code below and I have been having some difficulty understanding how the mechanics of the code. After reading different blogs and watching a few tutorials I came up with the below explanation. Could you please take a look and tell me if I am on the right track - it would save me many hours! (below is the solution we were given)
def my_each(&prc)
i = 0
while i < self.count
prc.call(self[i])
i += 1
end
self
end
def my_map(&prc)
result = []
my_each { |el| result << prc.call(el) }
result
end
array_k.my_map
By calling my_map on the array_k, we are implicitly calling my_each on array_k, passing the { |el| result << prc.call(el) } in the my_each method. When going through the loop in the my_each method, we call the proc (prc.call(self[i])) on each one of the elemenets of array_k and in our case, this proc is the block { |el| result << prc.call(el) }. The prc.call in the block iteself refers to the a proc that we have created that is will alter the elements of the array_k and create a new one by putting the altered element in the result array.
Am I on the right track?
Thanks a lot!
Upvotes: 2
Views: 143
Reputation: 26768
I think your explanation is correct and you do have the right idea.
The &proc
and proc.call
syntax is fine, but you could alternately write it using yield
like so:
def my_each
i = 0
while i < self.count
yield self[i]
i += 1
end
self
end
def my_map
result = []
my_each { |el| result << yield(el) }
result
end
Upvotes: 1