Bug #17398
SyntaxError in endless method
Description
This works:
def foo() = puts("bar")
This does not:
def foo() = puts "bar"
# ^ syntax error, unexpected string literal, expecting `do' or '{' or '('
Is this intentional or accidental? Not sure how it is reasoned.
Updated by mame (Yusuke Endoh) 3 months ago
The body of an endless method must be an expression (called "arg" in the syntax rules of parse.y). puts("bar")
is an expression, but puts "bar"
is a statement (called "command" in the syntax rules).
I think it could be a bit confusing, but I have no idea whether we can/should allow a statement as a body of an endless method.
Updated by zverok (Victor Shepelev) 3 months ago
mame (Yusuke Endoh) Hmm, haven't thought about it from this perspective... Can you please explain a bit? As far as I can see, in, say, assignment context it behaves like an expression:
result = puts 'foo'
# prints "foo", result = nil
I am just trying to describe the behavior in full for the next installment of my changelog and this aspect is quite confusing for me... Though, it is not endless-method specific, as far as I can see:
y = sin x # OK
y = 1 + sin x
# ^ unexpected local variable or method, expecting `do' or '{' or '('
What's the "rule of thumb" to understand this better?
Updated by Eregon (Benoit Daloze) 3 months ago
Conceptually, according to the typical definition in computer science, both puts("bar")
and puts "bar"
are expressions (i.e., they return a value, and if it was some other method than puts
it would also not always be nil
).
It might be slightly less clear for e.g. a = 42
(it's still an expression, it still returns a value), but I think puts "bar"
is clear that it should be the same as puts("bar")
, except for precedence.
So it's probably going to be very difficult to explain the actual condition, other than showing specific examples.
Updated by austin (Austin Ziegler) 3 months ago
Eregon (Benoit Daloze) wrote in #note-3:
So it's probably going to be very difficult to explain the actual condition, other than showing specific examples.
Endless methods definitions don’t support poetry mode?
Updated by mame (Yusuke Endoh) 3 months ago
The following patch allows def foo() = puts "bar"
. It brings no parser conflict.
https://gist.github.com/mame/0773bf3938e046e2b608de5fb2a826c8
However, it is not perfect. private def foo() = puts "foo"
does not parse.
private var = puts "bar"
is not allowed neither, so I have no idea how to allow this.