From: "jeremyevans0 (Jeremy Evans)" Date: 2022-03-14T22:47:40+00:00 Subject: [ruby-core:107905] [Ruby master Bug#18633] proc { |a, **kw| a } autosplats and treats empty kwargs specially Issue #18633 has been updated by jeremyevans0 (Jeremy Evans). Eregon (Benoit Daloze) wrote: > ```ruby > irb(main):005:0> proc { |a| a }.call([1, 2]) > => [1, 2] > irb(main):006:0> proc { |a, **kw| a }.call([1, 2]) > => 1 # should be [1, 2] > irb(main):007:0> proc { |a, kw: 42| a }.call([1, 2]) > => 1 # should be [1, 2] > ``` > > What's the reason for `proc { |a, **kw| a }` to autosplat? > It seems inconsistent with the resolution of #16166, and it seems nobody would want that behavior (it loses arguments but the user extremely likely did not want that). > Could we change it so procs never autosplat, just like `proc { |a| a }`. I agree that there is no reason to autosplat in this case on Ruby 3 (autosplatting made sense in Ruby 2). I changed the `*a, **kw` case in #16166, because that is the case @matz indicated he wanted to change (https://bugs.ruby-lang.org/issues/16166#note-6). @matz didn't indicate he wanted the behavior of `a, **kw` or `a, kw: ` changed, so I didn't make changes to that behavior. Like #18625, this change seems too risky to backport, and there doesn't seem to be a way to properly deprecate it. So I also recommend we make this change in 3.2 and not backport it. > Also I noticed: > ```ruby > irb(main):010:0> proc { |a, **kw| a }.call([1, 2]) > => 1 > irb(main):011:0> proc { |a, **kw| a }.call([1, 2], **{}) > => [1, 2] > ``` > Which is really unfortunate as it shows a difference between passing `**{}` or nothing. > AFAIK passing `**{}` or nothing should always be equivalent, but it breaks in this case. > > (from https://bugs.ruby-lang.org/issues/16166#note-14) At least this behavior is deliberate. We don't want `proc { |a, **kw| a }.call([1, 2], **h)` to result in `a` sometimes being `1` and other times being `[1, 2]` based on the value of `h`. Always using `[1, 2]` for `a` seems fine. ---------------------------------------- Bug #18633: proc { |a, **kw| a } autosplats and treats empty kwargs specially https://bugs.ruby-lang.org/issues/18633#change-96843 * Author: Eregon (Benoit Daloze) * Status: Open * Priority: Normal * Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- ```ruby irb(main):005:0> proc { |a| a }.call([1, 2]) => [1, 2] irb(main):006:0> proc { |a, **kw| a }.call([1, 2]) => 1 # should be [1, 2] irb(main):007:0> proc { |a, kw: 42| a }.call([1, 2]) => 1 # should be [1, 2] ``` What's the reason for `proc { |a, **kw| a }` to autosplat? It seems inconsistent with the resolution of #16166, and it seems nobody would want that behavior (it loses arguments but the user extremely likely did not want that). Could we change it so procs never autosplat, just like `proc { |a| a }`. My understanding of the change in #16166 is to reflect the fact positional and kwargs are separated, and so adding `**kw` or `kw:` should never change anything if only positional arguments are passed. This breaks in this case though. Also I noticed: ```ruby irb(main):010:0> proc { |a, **kw| a }.call([1, 2]) => 1 irb(main):011:0> proc { |a, **kw| a }.call([1, 2], **{}) => [1, 2] ``` Which is really unfortunate as it shows a difference between passing `**{}` or nothing. AFAIK passing `**{}` or nothing should always be equivalent, but it breaks in this case. (from https://bugs.ruby-lang.org/issues/16166#note-14) -- https://bugs.ruby-lang.org/ Unsubscribe: