From: merch-redmine@... Date: 2019-06-04T14:40:58+00:00 Subject: [ruby-core:92960] [Ruby trunk Feature#15897] `it` as a default block parameter Issue #15897 has been updated by jeremyevans0 (Jeremy Evans). mikegee (Michael Gee) wrote: > > RSpec won't break because their "it" requires an argument > > Unfortunately this is not accurate. RSpec has a shorthand style like this: > > `subject { fortytwo } > it { is_expected.to eq 42 }` That's a block argument :). In any case, the parser treats it differently as NODE_ITER/NODE_FCALL, not as NODE_VCALL: ```ruby RubyVM::AbstractSyntaxTree.parse("it").children # => [[], nil, #] RubyVM::AbstractSyntaxTree.parse("it{}").children # => [[], nil, #] RubyVM::AbstractSyntaxTree.parse("it{}").children.last.children # => [#, #] ``` Regarding the proposal itself, the dirtying of the semantics bothers me about this as well. However, I can see where people would find `it` cleaner than `@` in terms of syntax, so this is really a tradeoff between the cleanliness of semantics and syntax. I don't have a strong opinion on `it` compared to `@`, but I think either is preferable to `@1` or `_`. ---------------------------------------- Feature #15897: `it` as a default block parameter https://bugs.ruby-lang.org/issues/15897#change-78338 * 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: