Actions
Bug #20970
open`it /1/i` raises undefined method 'it' for main (NoMethodError) even if binding.local_variables includes `it`
Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 3.4.0dev (2024-12-19T07:16:12Z master 335bba0fde) +PRISM [x86_64-linux]
Description
it
parameter became a local variable with #20965, but it does not behave like local variable with --parser=prism
i=2
42.tap do
p it # 42
p local_variables # [:it, :i]
p it /1/i # should be 21, got NoMethodError
end
It prints 42
, [:it, :i],
21with
--parser=parse.y`
Updated by k0kubun (Takashi Kokubun) about 7 hours ago
- Related to Feature #18980: `it` as a default block parameter added
Updated by zverok (Victor Shepelev) about 6 hours ago
Interesting. Before the change (on 3.4.0dev (2024-12-15T13:36:38Z master 366fd9642f)
) it was an error both with Prism and parse.y:
$ ruby -e "i = 2; [1, 2, 3].each { it /1/i }"
-e:1:in 'block in <main>': undefined method 'it' for main (NoMethodError)
$ ruby --parser=parse.y -e "i = 2; [1, 2, 3].each { it /1/i }"
-e:1:in 'block in <main>': undefined method 'it' for main (NoMethodError)
As far as I can guess (by IRB syntax highlighting), it /1/i
parses at once as it(/1/i)
(with /1/i
treated as a regexp literal). Reproduced in other ambiguous cases (that are resolved by local name presence, for all I can understand), say:
ruby -e "[1, 2, 3].each { it + 1 }"
#=> OK
$ ruby -e "[1, 2, 3].each { it +1 }"
-e:1:in 'block in <main>': undefined method 'it' for main (NoMethodError)
$ ruby -e "[1, 2, 3].each { |it| it +1 }"
#=> OK
I.e., ambiguous operators parsing decisions are made based on whether it
is known to be a local var (then it is it.+(1)
), or not known (then it is tentatively considered it(+1)
).
Updated by zverok (Victor Shepelev) about 6 hours ago
- Backport changed from 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN to 3.1: DONTNEED, 3.2: DONTNEED, 3.3: DONTNEED
Actions
Like0
Like0Like0Like0