Search code examples
rubyrspecsplat

Is there a way without a (*)splat argument to pass multiple arguments in Ruby?


I need to write a method that takes an unknown number of arguments (hence the *splat) but that passes a yields_with_args spec.

The code:

def eval_block(*args, &block)
    raise "NO BLOCK GIVEN!" if block.nil?
       block.call(args)
end

The rspec:

it "passes the arguments into the block" do
      expect do |block|
        eval_block(1, 2, 3, &block)
      end.to yield_with_args(1, 2, 3)
    end
end

It works, but it yields the array that *splat creates: [1,2,3] vs 1,2,3, and therefore doesn't pass the rspec. Is there another way to pass on multiple arguments through a method in Ruby?


Solution

  • Replace

    block.call(args)
    

    with

    block.call(*args)
    

    Splat has two functions: collecting arguments to an array when in definition, and distributing an array to arguments in calls. The two are inverse operations: if you expect transparent operation (three arguments go in, three arguments go out), you should distribute what you collected.