Ben Crouse
Ben Crouse

Reputation: 8348

How can I programmatically pass args to yield in Ruby?

How can I pass a variable number of args to a yield. I don't want to pass an array (as the following code does), I'd actually like to pass them as a programmatic number of args to the block.

def each_with_attributes(attributes, &block)
  results[:matches].each_with_index do |match, index|
    yield self[index], attributes.collect { |attribute| (match[:attributes][attribute] || match[:attributes]["@#{attribute}"]) }
  end
end

Upvotes: 12

Views: 4580

Answers (3)

Andru Luvisi
Andru Luvisi

Reputation: 25308

Use the splat-operator * to turn the array into arguments.

block.call(*array)

or

yield *array

Upvotes: 15

Robert Gamble
Robert Gamble

Reputation: 109012

Use the asterisk to expand an array into its individual components in an argument list:

def print_num_args(*a)
  puts a.size
end

array = [1, 2, 3]
print_num_args(array);
print_num_args(*array);

Will print:

1
3

In the first case the array is passed, in the second case each element is passed separately. Note that the function being called needs to handle variable arguments such as the print_num_args does, if it expects a fixed size argument list and received more or less than expected you will get an exception.

Upvotes: 4

Dustin
Dustin

Reputation: 90980

Asterisk will expand an array to individual arguments in ruby:

def test(a, b)
  puts "#{a} + #{b} = #{a + b}"
end

args = [1, 2]

test *args

Upvotes: 2

Related Questions