Issue #19392 has been updated by zverok (Victor Shepelev).
@nobu
It depends on how you define "expressions".
At least in Ruby's terms, any method definition can be an argument of other method
calls.
Thank you, I am well aware of this. (I maintain [Ruby
Changelog](https://rubyreferences.github.io/rubychanges/), including [detailed
explanations](https://rubyreferences.github.io/rubychanges/3.0.html#improved-method-visibility-declaration)
on how and why methods as expressions can be used.)
To utilize this, def returns the ID since 2.3.
Since [2.1](https://rubyreferences.github.io/rubychanges/evolution.html#methods), actually
:)
That's why I didn't say, "method definitions aren't expressions", I
said, "method definitions aren't **any** expressions", meaning that while
being _expressions_ indeed, they still behave differently in several important aspects
from most the other expressions.
One of those aspects is the creation of its own scope.
Endless methods do it without explicit ending sign (like, `}` or `end`). This makes
"where the expression ends" an extremely sensitive question, which, I believe,
shouldn't be brushed off easily.
----------------------------------------
Bug #19392: Endless method vs and/or
https://bugs.ruby-lang.org/issues/19392#change-101602
* Author: zverok (Victor Shepelev)
* Status: Open
* Priority: Normal
* Backport: 2.7: DONTNEED, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
[
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"
```
--
https://bugs.ruby-lang.org/