Refactoring binary search algorithm in Ruby
Rather than defining it at the top level, why don't you make it a new method on Array?
Taking l and r makes recursive calls possible, but would be annoying for the end user who always has to pass 0 and array.length-1. You should either make those arguments optional, or don't use recursion, or use a private helper method for the recursion.
Someone suggested you could make it tail-recursive, but I don't think any Ruby implementation I know of can optimize tail recursion, so I'm not sure what the point of that would be. Method calls are expensive in Ruby, so if you are after performance, I think a while loop would be more appropriate.
You could consider calling &lt;=&gt; once and switching on the return value using case. I'm not sure if you would like the way this reads better or not. If performance is important, definitely try it and benchmark both ways.
If you do want to use if statements, the 3rd if is redundant.
You are using the type of binary search which has 3 different branches (depending on whether the value at the probed index is &gt;, &lt;, or == to the value you are searching for). There is another to write a binary search which only uses a single if-else, which is more concise, generally faster, and which is guaranteed to return the first matching element in the array (if there are duplicates).