From: "Eregon (Benoit Daloze)" Date: 2022-03-14T12:41:50+00:00 Subject: [ruby-core:107890] [Ruby master Feature#16166] Remove exceptional treatment of *foo when it is the sole block parameter Issue #16166 has been updated by Eregon (Benoit Daloze). What's the reason for this behavior? It seems inconsistent with the resolution of this issue, and it seems nobody would want that behavior: ```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 irb(main):007:0> proc { |a, kw: 42| a }.call([1, 2]) => 1 ``` Also: ```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 as it shows a difference between passing `**{}` or nothing (a bug I guess?). ---------------------------------------- Feature #16166: Remove exceptional treatment of *foo when it is the sole block parameter https://bugs.ruby-lang.org/issues/16166#change-96831 * Author: sawa (Tsuyoshi Sawada) * Status: Closed * Priority: Normal ---------------------------------------- In the parameter signature of a code block for a method that is not involved in method definition or creation of lambda objects, two types of arguments `["a"]` and `"a"` are neutralized: ```ruby instance_exec(["a"]){|foo, bar| foo} # => "a" instance_exec("a"){|foo, bar| foo} # => "a" instance_exec(["a"]){|*foo, **bar| foo} # => ["a"] instance_exec("a"){|*foo, **bar| foo} # => ["a"] ``` This is the same behavior as with assignment constructions: ```ruby foo, bar = ["a"]; foo # => "a" foo, bar = "a"; foo # => "a" *foo = ["a"]; foo # => ["a"] *foo = "a"; foo # => ["a"] ``` And it contrasts with constructions involved in method definition or creation of lambda objects, where the distinction is preserved: ```ruby lambda{|foo| foo}.call(["a"]) # => ["a"] lambda{|foo| foo}.call("a") # => "a" ->(foo){foo}.call(["a"]) # => ["a"] ->(foo){foo}.call("a") # => "a" lambda{|*foo| foo}.call(["a"]) # => [["a"]] lambda{|*foo| foo}.call("a") # => ["a"] ->(*foo){foo}.call(["a"]) # => [["a"]] ->(*foo){foo}.call("a") # => ["a"] ``` However, when `*foo` is the sole parameter of a code block for a method that is not involved in method definition or creation of lambda objects, `["a"]` and `"a"` are not neutralized: ```ruby instance_exec(["a"]){|*foo| foo} # => [["a"]] instance_exec("a"){|*foo| foo} # => ["a"] ``` behaving in contrast to assignment constructions, and rather on a par with constructions involved in method definition or creation of lambda objects. Particularly, existence or absence of another parameter `**bar` entirely changes what `foo` refers to: ```ruby instance_exec(["a"]){|*foo| foo} # => [["a"]] instance_exec(["a"]){|*foo, **bar| foo} # => ["a"] ``` I find this behavior inconsistent and confusing. I would like to request to remove this exceptional treatment of splatted parameter `*foo` when it is the sole parameter in a code block. I request this behavior: ```ruby instance_exec(["a"]){|*foo| foo} # => ["a"] ``` -- https://bugs.ruby-lang.org/ Unsubscribe: