Passing a block to a method recursively in ruby
def bubble_sort_by nums
do_it_again = false
nums[0...-1].each_with_index do |item, index|
if yield(nums[index], nums[index + 1]) > 0
nums[index], nums[index + 1] = nums[index + 1], nums[index]
do_it_again = true
end
end
bubble_sort_by nums if do_it_again
nums
end
bubble_sort_by(["hi","hello","hey"]) do |left,right|
right.length - left.length
end
The program sorts the bubbles based on the block. In this case, the block is sorted by length. So I am getting a local navigation error. Took me a little, but I figured it out. When I call a method recursively, I am not giving it a block. But how can I do this?
+3
source to share
2 answers
yield + block_given solution is one-off, you cannot use it in recursive calls without explicitly passing & block or Proc (closure) as an argument, although it does give you better performance empirically.
Here is some dummy code (a custom version of the map function) to make recursive calls
passing Proc as normal object
def mymap(xs, f)
if xs.empty?
[]
else
hd, *tl = xs
[f.call(hd)]+ mymap(tl,f)
end
end
mymap([1,2,3], lambda {|x| x*2})
transfer optinal & block
def mymmap(xs, &block)
if xs.empty?
[]
else
hd, *tl = xs
[block.call(hd)]+ mymmap(tl, &block) #here yield(hd) will do as well
end
end
mymmap([1,2,3]){|x| 2*x} #notice the calling manner is different from the above
0
source to share