From: "zverok (Victor Shepelev) via ruby-core" Date: 2023-03-02T08:43:06+00:00 Subject: [ruby-core:112661] [Ruby master Bug#19392] Endless method vs and/or Issue #19392 has been updated by zverok (Victor Shepelev). `and` is actually not alone. The code like this is also parsed not the way one would intuitively expect: ```ruby def save = File.write(name, self.to_yaml) unless invalid? ``` Actual parsing is this: ```ruby (def save = File.write(name, self.to_yaml)) unless invalid? ``` I believe that combining postfix `if`/`unless` with one-line methods is extremely possible, while intention to conditionally define methods with postfix condition is much less so. In general, I believe that ```ruby def method expression end ``` and ```ruby def method = expression ``` should be equivalent as long as it is humanly possible, because the simplification of one-expression method to endless one is what many codebases would try to do, especially for simple utility classes. And if they can't be made equivalent (due to some parser complexities), the only other acceptable behavior is an error or at least warning (though the latter is much less desirable), not a silent change of semantics. ---------------------------------------- Bug #19392: Endless method vs and/or https://bugs.ruby-lang.org/issues/19392#change-102110 * 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/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/