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


jeremyevans0 (Jeremy Evans) wrote:
> The behavior changes  if `foo` is a local variable:
> ```ruby
> foo = 1
> proc{foo &1}.call
> # => 1
> proc{foo & 1}.call
> # => 1
> ```

Good catch, I forgot about that case.
Indeed, that's a bit confusing.
This case can be worked around with parentheses if there is a local variable of the same name: `foo(&1)`.
(This issue already exists if there is a variable of the same name and the method takes no argument; it then needs explicit parentheses or receiver: `foo=1; foo()`)

I think a possible way to solve this is to make `&1`, `&2`, ... special in the lexer (e.g., a `/(\s+|delimiter)&[1-9]/` rule), so they follow the spacing rules, ignoring whether LHS is a variable or something else.
Another way to see this is tweaking the rule for distinguishing unary and binary operators, so that for `&1` there is no special behavior if LHS is a variable.

> This proposal has the following issue, where the same token (`&1`) could mean different things:
> I think using `&1` would cause problems, because any time you passed it as the last argument to a method, it would ambiguous as to whether you mean Integer#to_proc or the implicit block argument.

I think that can be solved easily with "unary & + integer literal" becoming a single AST node and expression, so they always mean "block parameter" and never "Integer#to_proc".
(We'd anyway change the semantics of when `Integer#to_proc` is called, I think basically nobody uses `Integer#to_proc`, and making it clear is better)

----------------------------------------
Misc #15723: Reconsider numbered parameters
https://bugs.ruby-lang.org/issues/15723#change-77598

* Author: sos4nt (Stefan Schler)
* Status: Feedback
* Priority: Normal
* Assignee: 
----------------------------------------
I just learned that *numbered parameters* have been merged into Ruby 2.7.0dev.

For readers not familiar with this feature: it allows you to reference block arguments solely by their *index*, e.g.

```ruby
[1, 2, 3].each { |i| puts i }

# can become

[1, 2, 3].each { puts @1 }
```

I have an issue with this new feature: I think **it encourages sloppy programming** and results in **hard to read code**.

---

The [original proposal](https://bugs.ruby-lang.org/issues/4475) was to include a special variable (or keyword) with a **readable name**, something like:

```ruby
[1, 2, 3].each { puts it }

# or

[1, 2, 3].each { puts this }
```

Granted, that looks quite lovely and it actually speaks to me  I can *understand* the code. And it fits Ruby: (quoting the website)

> [Ruby] has an elegant syntax that is natural to read and easy to write.

But the proposed `it` / `this` has limited application. It's only useful when dealing with a single argument. You can't have multiple `it`-s or `this`-es. That's why `@1`, `@2`, `@3` etc. were chosen instead.

However, limiting the usefulness to a single argument isn't bad at at. In fact, a single argument seem to be the limit of what makes sense:
```
h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }

# vs

h = Hash.new { @1[@2] = "Go Fish: #{@2}" }
```
Who wants to read the latter? That looks like an archaic bash program (no offense). We already discourage Perl style `$`-references: (from [The Ruby Style Guide](https://github.com/rubocop-hq/ruby-style-guide#no-perl-regexp-last-matchers))

> Don't use the cryptic Perl-legacy variables denoting last regexp group matches (`$1`, `$2`, etc). Use `Regexp.last_match(n)` instead.

I don't see how our code can benefit from adding `@1` and `@2`.

Naming a parameter isn't useless  it gives context. With more than one parameter, naming is crucial. And yes, naming is hard. But avoiding proper naming by using indices is the wrong way.

So please reconsider numbered parameters.

Use a readable named variable (or keyword) to refer to the first argument or ditch the feature entirely.



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