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"]
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"]
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"]
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