IliasP
IliasP

Reputation: 91

Emulating the each and map method without using each and map. Explanation on the mechanics of the code needed

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

Answers (1)

max pleaner
max pleaner

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

Related Questions