You can't pass an arbitrary number of arguments to a ruby method without declaring it in the method definition. Passing just *args
works because since *args is empty, it's basically as though you're passing no arguments to the methods, which is what my_method expects. With kwargs
, you're passing the empty hash as an argument. Since the method is declared to take no arguments, this raises the error.
In general, the way to do this in ruby would be something like this:
def my_method(*args, **kwargs)
'I have run correctly'
end
If a ruby method can accept an indefinite number of arguments, or keyword arguments, it needs to be explicit in the definition of the method.
More frequently however, you'll see idioms like this:
def my_method(arg, opts={})
# do something
end
# Invoke the method like this:
# args == ['argument', 'another argument']
# opts == {opt1: 'val1', opt2: 'val2'}
my_method('some argument', opt1: 'val1', opt2: 'val2')
As to your observation about my_method *args, **kwargs
acting differently than my_method *args, **{}
... I'll first say that if your motivation is first and foremost about learning Ruby, then I would reemphasize my above point that kwargs are not a commonly used in Ruby, at least not in the same way they are used in Python.
And after that I'll say that this is very strange.
I notice that:
[**kwargs] # => [{}]
[**{}] # => []
# And even more interesting:
[**{}.itself] # => [{}]
So I was correct in saying that with **kwargs
, the interpreter complains because you're passing the empty hash to a method that doesn't expect any arguments. But as to why that is different from **{}
, I'm not sure. I'm digging into now, but my current suspicion is honestly that this is a fluke of the interpreter. There's no reason that these should be evaluated different just because one the two is assigned to a variable...
What's more, the double-splat operator's adoption isn't super widespread, largely because of the preference for the opts={}
idiom described above. Also this isn't a use case many would run into in practice. A programmer would have to explicitly pass the empty hash to such a method when they could (regardless of whether kwargs or opts) just omit the argument. So yeah... I think this might be fluke of the interpreter.