rellampec
rellampec

Reputation: 752

Collecting keyword arguments in Ruby

Just trying to understand how to collect arguments in Ruby, I came up with the following snippet, that seems to fail to collect keyword arguments in **kargs in some case:

def foo(i, j= 9, *args, k: 11, **kargs)
  puts "args: #{args}; kargs: #{kargs}"
end

foo(a: 7, b: 8)
# output: args: []; kargs: {}
foo(9, a: 7, b: 8)
# output: args: []; kargs: {:a=>7, :b=>8}
foo(9, 10, 13, a: 7, b: 8)
# output: args: [13]; kargs: {:a=>7, :b=>8}

I would like to know why it does not collect kargs in the first call to foo, while in the second call it does.

Upvotes: 2

Views: 763

Answers (1)

Simple Lime
Simple Lime

Reputation: 11035

It's because the first parameter i, is a required parameter (no default value), so, the first value passed to the method (in your first example, this is the hash {a: 7, b: 8}) is stored into it.

Then, since everything else is optional, the remaining values (if any, in this example, there are none) are filled in, as applicable. IE, the second parameter will go to j, unless it is a named parameter, then it goes to kargs (or k). The third parameter, and any remaining--up until the first keyword argument, go into args, and then any keyword args go to kargs

def foo(i, j= 9, *args, k: 11, **kargs)
  puts "i: #{i}; args: #{args}; kargs: #{kargs}"
end

foo(a: 7, b: 8)
# i: {:a=>7, :b=>8}; args: []; kargs: {}

Upvotes: 5

Related Questions