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


I like the proposal and I think it reads nicer than `@`.
It's a bit magical that giving it an argument changes the semantics, but that's somewhat similar to having a `p` local variable, and I think it's worth the better readability and syntax.
Not so many people seem confused by `p` so I guess it would not be too surprising and just intuitive in common cases.

I also like `_` because `_` is "unnamed" (rather than abstract like `it`) and a "placeholder for the missing argument name" and this whole feature is about removing the need to name the block argument.
Showing them in code for an easy comparison:

```ruby
[1, 2, 3].map { @ * 3 }
[1, 2, 3].map { @1 * 3 }
[1, 2, 3].map { _ * 3 }
[1, 2, 3].map { it * 3 }
[1, 2, 3].map { |n| n * 3 }
```

In the case of nested unnamed block arguments (`[1].map { _ * 3.then { _ } }`), both `_` and `it` would refer to the outer block's argument, and consider the inner block(s) have no arguments.
That could be confusing, it might worth warning or rejecting such cases, although they are probably rare.

> But it would be much better than Perlish `@1`

Strongly agreed.

----------------------------------------
Feature #15897: `it` as a default block parameter
https://bugs.ruby-lang.org/issues/15897#change-78343

* Author: mame (Yusuke Endoh)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version: 
----------------------------------------
How about considering "it" as a keyword for the block parameter only if it is the form of a local varaible reference and if there is no variable named "it"?

```
[1, 2, 3].map { it.to_s } #=> ["1", "2", "3"]
```

If you are familiar with Ruby's parser, this explanation is more useful: NODE_VCALL to "it" is considered as a keyword.

Examples:

```
public def it(x = "X")
  x
end

[1, 2, 3].map { it.to_s }    #=> ["1", "2", "3"]
[1, 2, 3].map { self.it }    #=> ["X", "X", "X"] # a method call because of a receiver
[1, 2, 3].map { it() }       #=> ["X", "X", "X"] # a method call because of parentheses
[1, 2, 3].map { it "Y" }     #=> ["Y", "Y", "Y"] # a method call because of an argument
[1, 2, 3].map { it="Y"; it } #=> ["Y", "Y", "Y"] # there is a variable named "it" in this scope

it = "Z"
[1, 2, 3].map { it.to_s }    #=> ["Z", "Z", "Z"] # there is a variable named "it" in this scope
```

Pros:
* it is the best word for the feature (according to @matsuda)
* it is reasonably compatible; RSpec won't break because their "it" requires an argument

Cons:
* it actually brings incompatibility in some cases
* it is somewhat fragile; "it" may refer a wrong variable
* it makes the language semantics dirty

Fortunately, it is easy to fix the incompatible programs: just replace `it` with `it()`.  (Off topic: it is similar to `super()`.)
Just inserting an assignment to a variable "it" may affect another code.  This is a bad news, but, IMO, a variable named "it" is not so often used.  If this proposal is accepted, I guess people will gradually avoid the variable name "it" (like "p").
The dirtiness is the most serious problem for me.  Thus, I don't like my own proposal so much, honestly.  But it would be much better than Perlish `@1`.  (Note: I don't propose the removal of `@1` in this ticket.  It is another topic.)  In any way, I'd like to hear your opinions.


An experimental patch is attached.  The idea is inspired by @jeremyevans0's [proposal of `@`](https://bugs.ruby-lang.org/issues/15723#note-98).


P.S. It would be easy to use `_` instead of `it`.  I'm unsure which is preferable.

---Files--------------------------------
its.patch (4.92 KB)


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