[ruby-core:95996] [Ruby master Feature#16166] Remove exceptional treatment of *foo when it is the sole block parameter

[email protected]
Newsgroups gmane.comp.lang.ruby.core
Message-ID <redmine.journal-82832.20191127175504.d92053670a77ef4a@ruby-lang.org>
Issue #16166 has been updated by Eregon (Benoit Daloze).


@sawa wrote this in the dev-meeting ticket:
> Unintended arity. This must be fixed in an earlier stage before Ruby 3.

I think matz conclusion is all behavior shown in this bug so far is intended, except for `*foo, **bar`.

@Dan0042
```
proc{ |a,b| [a,b] }.call(1,2)   #=> [1, 2]
proc{ |*ab| ab    }.call(1,2)   #=> [1, 2]
proc{ |a,b| [a,b] }.call([1,2]) #=> [1, 2]
proc{ |*ab| ab    }.call([1,2]) #=> [[1, 2]]
```
That's just how Proc works, multiple parameters will splat an Array if a single Array argument is given.

I think long-term we might want to use lambda semantics by default for blocks, which doesn't have that splatting magic.

----------------------------------------
Feature #16166: Remove exceptional treatment of *foo when it is the sole block parameter
https://bugs.ruby-lang.org/issues/16166#change-82832

* Author: sawa (Tsuyoshi Sawada)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
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: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.