Issue #15078 has been updated by marcandre (Marc-Andre Lafortune).


First, I hope we can agree that `any(**{})` and `any(**Hash.new)` should have the exact same result (for any definition of `any`).

So the question is: what should the result be?

For me, writing `**hash` means "do as if I had written that hash inline".
I.e. `any(**{k1: 1, k2: 2})` should have the exact same result as `any(k1: 1, k2: 2)`
In the same way, `any(**{})` should have the exact same result as `any()`

Advantages I see:
a) Allows two ways to safely forward all arguments to another method:

```
def middle(*args, &b)
  forward_to(*args, &b)
end

# or equivalently
def middle(*args, **options, &b)
  forward_to(*args, **options, &b)
end
```

In either cases, calling `middle(...)` has same effect as `forward_to(...)`.

My guess is that a huge number of `method_missing` definitions (like that of `lib/delegate`: https://github.com/ruby/ruby/blob/trunk/lib/delegate.rb#L78-L89) use either formulas to forward calls, for example.

b) Compatible with current behavior for most methods (those without positional rest argument)

```
empty_hash = {}
def foo(a, b); end; foo(1, 2, **empty_hash) # => no error
def foo(a, b=nil); end; foo(1, 2, **empty_hash) # => no error
```

Of course, one wouldn't write such code, but this is related to the previous point.

mame (Yusuke Endoh) wrote:
> Do you think it is bad to accept a keyword hash (f2(**h)) as a normal parameter (def f2(h))? Yes, I agree.

I am convinced that the vast majority of rubyists would either write `def f2(options = {})` (old style), or `def f2(**options)` (new style). I think it is good to accept `f2(**h)` as a normal parameter `def f2(h = {})`.

> So I'm proposing #14183.

I understand the goal and I completely agree that if we were to re-create Ruby from scratch it would be great. But Ruby is more than 20 years old with over 100k gems. Because of that my position has to be strongly against the proposal.

Now even if the proposal was accepted and implemented, then `**{}` would still never create a positional argument! So I believe that you actually agree with me :-)

----------------------------------------
Bug #15078: Hash splat of empty hash should not create a positional argument.
https://bugs.ruby-lang.org/issues/15078#change-73930

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
* Assignee: nobu (Nobuyoshi Nakada)
* Target version: 
* ruby -v: ruby 2.6.0dev (2018-08-27 trunk 64545) [x86_64-darwin15]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
Looks like #10856 is not completely fixed, but I can't reopen it

```
def foo(*args); args; end
foo(**{}) # => []
foo(**Hash.new) # => [{}], should be []
```



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

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>