Issue #16519 has been updated by Eregon (Benoit Daloze).


jeremyevans0 (Jeremy Evans) wrote:
> With ruby2_keywords by default, it's used for all methods accepting args splat and not keywords, making this type of issue much more common.

Do you have any existing real code example where that branch causes problems?
I agree it is more likely to have a few problems similar to this one than explicit `ruby2_keywords`.
OTOH, it would also make migrating thousands of delegation calls (i.e., all delegation cases passing kwargs) so much easier.
It's a trade-off. I'd take one case like this needing `, **{})` over finding where to add 1000 explicit `ruby2_keywords` any day.

BTW, this case is interesting, because we cannot say "this is a misuse of ruby2_keywords".
Printing arguments for debugging with `pp` should work of course.
It's really case unique of its kind that way.
In almost all other cases (>99%), passing `*args` around has the intention to delegate keyword arguments as-is in Ruby 2.6 code.

> This is by design.  Empty keyword splats are equivalent to passing no arguments, just as empty regular splats are equivalent to passing no arguments.  I consider the Ruby <2.7 behavior a bug in this regard.  When you consider that `**{}` never passed arguments (was removed by the parser), I think the intended behavior for empty keyword splats was not to pass arguments.

Yes, I understand this point of view. But the fact is when calling a method not accepting keyword arguments, with syntactic keywords, there is inconsistency between empty keyword arguments and non-empty as shown above.
That's clearly not ideal and makes thinking about `**` complicated because it might pass a positional argument or not.
It's something we could have avoided by raising if the method does not accept keyword arguments (but that's probably too incompatible).

> I think the current behavior of always removing empty keyword splats (including implicit splats of empty flagged hashes) makes much more sense.

It's also the only construct in Ruby where a Hash argument can fully disappear.
I'd argue if the user passed keyword arguments (e.g., with `**h`), even empty they should be preserved and not ignored, especially when calling a method not accepting keyword arguments.
I think removing it is counter-intuitive in some cases: for example it causes these weird cases for `p(**empty_hash)` which prints nothing when `p(**non_empty)` prints as expected.

----------------------------------------
Bug #16519: pp [Hash.ruby2_keywords_hash({})] shows `[nil]`
https://bugs.ruby-lang.org/issues/16519#change-84030

* Author: Eregon (Benoit Daloze)
* Status: Closed
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.8.0dev (2020-01-21T13:45:10Z master 5798d35ff6) [x86_64-linux]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: REQUIRED
----------------------------------------
This happens on `master`:

```
$ ruby -ve 'ruby2_keywords def flag(*a); a.last; end; pp [flag(**{})]'
ruby 2.8.0dev (2020-01-21T13:45:10Z master 5798d35ff6) [x86_64-linux]
[nil]
```

Of course it should be `[{}]`, as it is for `pp [{}]`.

On 2.7.0 it warns (should be fixed, it's valid to `pp` a flagged Hash):
```
$ ruby -ve 'ruby2_keywords def flag(*a); a.last; end; pp [flag(**{})]'
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux]
[/home/eregon/.rubies/ruby-2.7.0/lib/ruby/2.7.0/pp.rb:226: warning: Passing the keyword argument as the last hash parameter is deprecated
/home/eregon/.rubies/ruby-2.7.0/lib/ruby/2.7.0/pp.rb:334: warning: The called method is defined here
{}]
```

The warning being in the middle of the output is a fun fact here.
Lines it refers to (still the same on current master):
https://github.com/ruby/ruby/blob/v2_7_0/lib/pp.rb#L226
https://github.com/ruby/ruby/blob/v2_7_0/lib/pp.rb#L334

This is very confusing as it can happen during `test-all` and then show output such as:
```
<[{:a=>1}]> expected but was
<[{:a=>1}, nil]>.
```
when the reality is (can be verified with `p` before the `assert_equal`):
```
<[{:a=>1}]> expected but was
<[{:a=>1}, {}]>.
```



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