Issue #10708 has been updated by Damien Robert.


@Kolja: I wasn't aware of your post on stackoverflow when I posted this bug report, but this is indeed a nice coincidence!
For context I sometime want to apply some methods from a module without including the module, so I have a function 'apply' that takes
an unbound method, bind it to an object and send the arguments to this method. Since the object to bind to and the method itself are passed as
keywords to 'apply', I can't use
    method.call(*args,&block)
I need to call
    method.call(*args,**opts,&block)
where I stumbled upon the above bug when opts is empty.

@David: more precisely ruby select keywords as symbols keys of the last argument when it is of Hash type.
When you _call_ a function, using keyword like arguments is a syntaxtic sugar for passing a hash of symbols as the last argument. 
Now consider this:
    amethod({keyword: true})
is the same as
    amethod(keyword: true)
but
    amethod({keyword1: true}, keyword2: true) #one argument and one keyword
is not the same as
    amethod(keyword1: true, keyword2: true) #two keywords
And
    amethod(**{keyword1: true}, keyword2: true) #two keywords
do indeed gives only keywords in ruby already.

So that's why **{} should not be the same as {} but instead expand into 'nothing'.

@Nobuyoshi: thanks for the consideration!

----------------------------------------
Bug #10708: In a function call, double splat of an empty hash still calls the function with an argument
https://bugs.ruby-lang.org/issues/10708#change-50953

* Author: Damien Robert
* Status: Assigned
* Priority: Normal
* Assignee: Yukihiro Matsumoto
* ruby -v: ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-linux]
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
Consider this:

~~~ruby
def foo; end
foo(*[]) #Splatting an empty list is ok
foo(**{}) #Double splatting an empty hash is like calling foo({}) which gives an error
~~~

This is annoying in a function that is a wrapper around another function and just process some keywords:

~~~ruby
def wrapper(*args, keyword: true, **others)
  puts keyword
  wrappee(*args,**others) #here this code will fail if others is empty
end
~~~




-- 
https://bugs.ruby-lang.org/