Issue #19392 has been updated by mame (Yusuke Endoh).
Status changed from Open to Closed
Discussed at today's dev meeting. Because `a = b and c` is interpreted as `(a = b) and
c`, it is natural that `def a = b and c` is interpreted as `(def a = b) and c`, as Matz
said in his comment #note-9. This decision didn't change even with the
implementation.
Just FYI: @yui-knk said he just wanted to show that the implementation was therotically
possible with parse.y, but that he did never like it.
If you really need it, it would be good to write a Rubocop cop or something to warn it.
----------------------------------------
Bug #19392: Endless method and parsing priorities
https://bugs.ruby-lang.org/issues/19392#change-105575
* Author: zverok (Victor Shepelev)
* Status: Closed
* Priority: Normal
* Backport: 2.7: DONTNEED, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
**Initial description**
[
Discovered](https://twitter.com/lucianghinda/status/1617783952353406977) by Lucian
Ghinda:
```ruby
def test = puts("foo") and puts("bar")
# prints "bar" immediately
test
# prints "foo"
```
It seems that it is a parser error, right?..
```ruby
RubyVM::AbstractSyntaxTree.parse('def test = puts("foo") and
puts("bar")')
# =>
# (SCOPE@1:0-1:38
# tbl: []
# args: nil
# body:
# (AND@1:0-1:38
# (DEFN@1:0-1:22
# mid: :test
# body:
# (SCOPE@1:0-1:22
# tbl: []
# args:
# (ARGS@1:0-1:8 pre_num: 0 pre_init: nil opt: nil first_post: nil post_num: 0
post_init: nil rest: nil kw: nil kwrest: nil block: nil)
# body: (FCALL@1:11-1:22 :puts (LIST@1:16-1:21 (STR@1:16-1:21 "foo")
nil))))
# (FCALL@1:27-1:38 :puts (LIST@1:32-1:37 (STR@1:32-1:37 "bar") nil))))
```
E.g. it is parsed as
```ruby
(def test = puts("foo")) and (puts("bar"))
```
...which is hardly intentional or have any practical use. The rightly parsed code in this
case _can_ have practical use, like
```ruby
def write(data) = File.write(@filename, data) == data.size or raise "Something went
wrong"
```
**Additional cases of what seems to be the same problem**
```ruby
def save = File.write(name, self.to_yaml) unless invalid?
# Parsed as:
(def save = File.write(name, self.to_yaml)) unless invalid?
```
...which makes it very hard for the users to diagnose the real reason, see #19731
```ruby
def initialize(a, b) = @a, b = a, b
# syntax error, unexpected ',', expecting end-of-input (SyntaxError)
# def initialize(a, b) = @a, b = a, b
# ^
# Again, parsed as
(def initialize(a, b) = @a), b = a, b
```
While this one is at least diagnosed early, in pathological cases, it might lead to very
subtle bugs:
```ruby
private def start = @operation, @conversion = :print, :to_s
```
This code doesn't throw a syntax error, but its effect is very far from expected.
Again, it is parsed as
```ruby
private( (def start = @operation), @conversion = :print, :to_s )
```
...and ends up in:
* defining a private method `start`
* making private methods `:print` and `:to_s`
--
https://bugs.ruby-lang.org/