From: merch-redmine@... Date: 2020-09-18T20:04:26+00:00 Subject: [ruby-core:100041] [Ruby master Bug#17178] Procs with kw:def/**kw lose elements when called with a single Array Issue #17178 has been updated by jeremyevans0 (Jeremy Evans). Eregon (Benoit Daloze) wrote in #note-2: > Is there a reason that keywords in procs cause autosplatting? > It seems counter-intuitive. > I would expect autosplatting depends on declared positional parameters only. Previously, the autosplatted argument could be used as keywords if they were a hash or implicitly convertible to a hash, though this is no longer true in Ruby 3. > I'd argue it's a bug, because we lose part of the arguments for seemingly no reason. > > Also keyword extension is supposed to be safe, right? Here it loses part of the arguments, which seems rather severe to me: > `proc { |a| p [a] }.call([1,2,3]) # => [[1, 2, 3]]` > `proc { |a, **kw| p [a,kw] }.call([1,2,3]) # => [1, {}]` (where are `2` and `3`??) > `proc { |a,| p [a] }.call([1,2,3]) # => [1]` this is OK, I'm explicitly discarding extra arguments. I agree that your suggested behavior makes more intuitive sense with Ruby 3 semantics, but not with Ruby 2 semantics. I'm not sure the loss of backwards compatibility is worth it, and this will break backwards compatibility. This is something @matz should decide. ---------------------------------------- Bug #17178: Procs with kw:def/**kw lose elements when called with a single Array https://bugs.ruby-lang.org/issues/17178#change-87591 * Author: Eregon (Benoit Daloze) * Status: Open * Priority: Normal * ruby -v: ruby 3.0.0dev (2020-09-18T09:12:58Z master e1cca08a6d) [x86_64-linux] * Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN ---------------------------------------- ``` $ ruby -ve '{a: 1}.each_pair { |a, kw: :def| p [a,kw] }' ruby 3.0.0dev (2020-09-18T09:12:58Z master e1cca08a6d) [x86_64-linux] [:a, :def] # bug, should be [[1, 2], :def] $ ruby -ve '{a: 1}.each_pair { |a, **kw| p [a,kw] }' ruby 3.0.0dev (2020-09-18T09:12:58Z master e1cca08a6d) [x86_64-linux] [:a, {}] # bug, should be [[1, 2], {}] ``` So the value of the key-value pair is lost and not assigned to any argument. This seems a general problem of Proc, not just #each_pair: ``` $ ruby -e 'proc { |a, kw: :def| p [a,kw] }.call(1,2)' [1, :def] # understandable $ ruby -e 'proc { |a, kw: :def| p [a,kw] }.call([1,2])' [1, :def] # bug, should be [[1, 2], :def] $ ruby -e 'proc { |a, **kw| p [a,kw] }.call(1,2)' [1, {}] # understandable $ ruby -e 'proc { |a, **kw| p [a,kw] }.call([1,2])' [1, {}] # bug, should be [[1, 2], {}] ``` -- 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>