Issue #14130 has been updated by jeremyevans0 (Jeremy Evans).


With the changes in #14183, keyword splats support non-symbol keys, so with the master branch you now get:

```
No source
SOURCE: {}, OPTS: {:length=>2000}
SOURCE: {:length=>2000}, OPTS: {}

Source is mixed hash
SOURCE: {}, OPTS: {"River name"=>"Mississippi", :length=>2000, "Country"=>"USA"}
SOURCE: {"River name"=>"Mississippi", :length=>2000, "Country"=>"USA"}, OPTS: {}
```

In Ruby 3, you will get:

```
No source
SOURCE: {}, OPTS: {:length=>2000}
# ArgumentError, because only keywords provided and no positional arguments, and at least one positional argument is required

Source is mixed hash
SOURCE: {}, OPTS: {"River name"=>"Mississippi", :length=>2000, "Country"=>"USA"}
# ArgumentError, because only keywords provided and no positional arguments, and at least one positional argument is required
```

This shows there is still work do to in 2.7 to warn cases where the behavior will change in Ruby 3.  In both cases, the calls to `test2` should emit a warning, because the method will raise an error in Ruby 3.

----------------------------------------
Bug #14130: Keyword arguments are ripped from the middle of hash if argument have default value
https://bugs.ruby-lang.org/issues/14130#change-81301

* Author: zverok (Victor Shepelev)
* Status: Open
* Priority: Normal
* Assignee: nobu (Nobuyoshi Nakada)
* Target version: 
* ruby -v: 
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN
----------------------------------------
Here is the code:

```ruby
def test1(source = {}, **opts)
  puts "SOURCE: #{source}, OPTS: #{opts}"
end

def test2(source, **opts)
  puts "SOURCE: #{source}, OPTS: #{opts}"
end

puts "No source"
test1(length: 2000) 
# 1. SOURCE: {}, OPTS: {:length=>2000} -- OK, it is reasonable.
test2(length: 2000) 
# 2. SOURCE: {:length=>2000}, OPTS: {} -- Exactly as expected.

puts
puts "Source is mixed hash"
test1('River name' => 'Mississippi', length: 2000, 'Country' => 'USA')
# 3. SOURCE: {"River name"=>"Mississippi", "Country"=>"USA"}, OPTS: {:length=>2000} -- It is already a bit weird
test2('River name' => 'Mississippi', length: 2000, 'Country' => 'USA')
# 4. SOURCE: {"River name"=>"Mississippi", :length=>2000, "Country"=>"USA"}, OPTS: {} -- The most weird thing!
```

My concern is cases (3) and (4). Ripping keyword argument from what from any logic looks like a _middle_ of a hash (3) is already pretty strange. But the fact that this behavior depends on whether first argument has or has not default value (3 vs 4) clearly looks like some bug?

Checked on several recent versions, including `ruby 2.5.0dev (2017-09-11 trunk 59836) [x86_64-linux]` (the last that is available on my RVM), behavior is consistent between them.



-- 
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>