Search code examples
arraysrubyreturnenumerator

`return` in Ruby Array#map


I have a method where I would like to decide what to return within a map function. I am aware that this can be done with assigning a variable, but this is how I though I could do it;

def some_method(array)
    array.map do |x|
      if x > 10
         return x+1 #or whatever
      else
         return x-1
      end
    end
end

This does not work as I expect because the first time return is hit, it returns from the method, and not in the map function, similar to how the return is used in javascript's map function.

Is there a way to achieve my desired syntax? Or do I need to assign this to a variable, and leave it hanging at the end like this:

def some_method(array)
    array.map do |x|
      returnme = x-1
      if x > 10
         returnme = x+1 #or whatever
      end
      returnme
    end
end

Solution

  • You don't need the variable. Return value of the block is value of last expression evaluated in it. In this case, the if.

    def some_method(array)
        array.map do |x|
          if x > 10
             x+1
          else
             x-1
          end
        end
    end
    

    Ternary operator would look nicer, I think. More expression-ish.

    def some_method(array)
      array.map do |x|
        (x > 10) ? x+1 : x-1
      end
    end
    

    If you insist on using return, then you could use lambdas. In lambdas, return behaves like in normal methods.

    def some_method(array)
      logic = ->(x) {
        if x > 10
          return x + 1
        else
          return x - 1
        end
      }
      array.map(&logic)
    end
    

    This form is rarely seen, though. If your code is short, it surely can be rewritten as expressions. If your code is long and complicated enough to warrant multiple exit points, then probably you should try simplifying it.