Idiomatic shorthand loops in Ruby

Augusts Bautra - Mar 11 - - Dev Community

Ruby has some of the sleekest looping idioms in all of coding, and with some idiomatic sugar, you can make them even more compact.

TL;DR - numbered block arguments are pretty good.

1. Call some method on each element

[1, 2].map(&:to_s)     #=> ["1", "2"]
[1, 2].map { _1.to_s } #=> ["1", "2"]
Enter fullscreen mode Exit fullscreen mode

2. Call some method with each element as the argument

def greet(object, volume)
  "Hi, #{object}, #{volume}"
end

guests = [[1, :loudly], [2, :quietly]]

guests.map { |args| greet(*args) }
#=> ["Hi, 1, loudly", "Hi, 2, quietly"]
guests.map { greet(_1, _2) }
#=> ["Hi, 1, loudly", "Hi, 2, quietly"]
Enter fullscreen mode Exit fullscreen mode

Kwargs work with numbered args quite well also:

def greet(name:)
  "Hi, #{name}"
end

guests = [{name: "Bob"}, {name: "Mary"}]

guests.map { |kwargs| greet(**kwargs) }
#=> ["Hi, Bob", "Hi, Mary"] 
guests.map { greet(**_1) }
#=> ["Hi, Bob", "Hi, Mary"] 
Enter fullscreen mode Exit fullscreen mode

2-b. (cryptic edition, don't use this!) Call some method with each element.

def greet(object)
  "Hi, #{object}"
end

[1, 2].map(&method(:greet))
#=> nil # some weirdness with inline return 
x = [1, 2].map(&method(:greet))
#=> ["Hi, 1", "Hi, 2"] # works with assignment, phew
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .