Reputation: 752
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
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