-1

what happens when *args passed to yield in ruby, in capture_helper.rb of rails I saw a statement where *args is passed to yield statement, what actually happens when we do so.

 buffer = with_output_buffer { value = yield(*args) }

where first parameter is builder object and second parameter is the block passed

Akshay
  • 29
  • 6

2 Answers2

2

With the * operator (splat operator) prefixing a variable (which must be an array or hash), the values of the array are extracted:

ary = [1, 2, 3]

def foo(a, b, c)
  a + b + c
end

foo(ary)
# => ArgumentError: wrong number of arguments (given 1, expected 3)

foo(*ary)
# 6

It's just the same with yield, except that the values are passed to the block:

def bar
  ary2 = [5, 6]
  yield(*ary2)
end

bar do |x, y|
  puts x + y
end
# 11
Christoph Petschnig
  • 4,047
  • 1
  • 37
  • 46
  • 1
    but, most of code i have seen, * is used in method definition to accept any number of parameters rather than argument list – Akshay Dec 05 '16 at 10:01
0

Splats have many uses in ruby. When you use a splat in a method call it turns an array into a list of arguments.

def test(*args)
  args
end

Consider these examples:

a = [1,2,3]
test(a)
# => [[1, 2, 3]]
test(1,2,3)
# => [1, 2, 3]
test(*a)
# => [1, 2, 3]

In the first example the array is treated as the first argument so the result is an array in an array. While *[1,2,3] de-structures the array so that we get the desired result.

This makes it extremely useful for calling methods that take a variable number of arguments. yield works just like any other method in this regard, as using a splat will de-structure the array in args and call the passed block with a list of arguments.

max
  • 96,212
  • 14
  • 104
  • 165