Feature #20054
closedReplace the use of `def` in endless method definitions with a new sigil
Description
I propose to remove the use of keyword def
from the syntax of endless method definition, and introduce a new sigil instead of it. There are several possibilities for what character to use as the sigil, but the most seemingly promising one to me at this point is the colon. So, instead of:
def foo = method_body
I propose to write
:foo = method_body
There a few reasons to dispense with def
in endless method definition.
First, the current syntax for endless method definition looks too similar to conventional method definition. Without endless method definition, we could already define a method in a single line:
def foo; method_body end
and compared to this, what the endless method definition does is that, it only saves you from typing the end
keyword just by replacing the semicolon with an equal sign. This actually had not made much sense to me. Just saving you from typing the keyword end
looks too small of a change for introducing new syntax. In order for endless method definition syntax to be justified (as a shorthand for conventional method definition), it needs to save more typing.
Second, in #19392, some people are claiming to change the precedence involving endless method definition. I agree with Matz and other developers who support the current precedence in which:
def foo = bar and baz
is interpreted as:
(def foo = bar) and baz
and I understand that the controversy is due to the look and feel of the keyword def
. def
has lower precedence than and
in conventional method definition, although =
has higher precedence than and
in variable/constant assignment. Mixing the low-precedence def
and the high-precedence =
into a single syntax was the cause of the trouble, according to my opinion.
Thence, we should get rid of def
. Once we do so, we need to distinguish endless method definition from variable/constant assignment in a new way. What came to my mind was to use a single character: a sigil.
Especially, using the colon seems to make sense to me for several reasons:
Most importantly, assignment to a symbol is impossible, and it currently raises a syntax error, so it would not conflict with variable/constant assignment syntax.
Within Ruby syntax, symbol is naturally used to represent a method name. For example, in foo(&:bar)
constructions, users are used to passing a method name as a symbol. Also, a method definition returns a symbol representing the method name. So, making the endless method definition syntax look superficially like an "assignment to a symbol" would make sense.
Updated by vo.x (Vit Ondruch) 11 months ago
How would you like to find such method in a code, e.g. using grep
?
I might be getting old, but I still prefer:
{:foo => bar}
foo.each {|bar| ... }
def foo
...
end
Instead all the new shorter syntaxes.
Updated by rubyFeedback (robert heiler) 11 months ago
Thence, we should get rid of def
I am not sure this is possible. People kind of adjusted to
def.
Within Ruby syntax, symbol is naturally used to represent
a method name
While I agree, symbols are also used elsewhere, such as for
arguments to methods.
For instance, in a few projects I use an API such as this:
enable :colours
(Which in turn calls the method enable_colours; I have a generic
enable method, and then use Symbols for that to designate entry
points. Correspondingly I also then use: disable :colours to
toggle onto the alternate state.)
making the endless method definition syntax look superficially
like an "assignment to a symbol" would make sense.
Personally I don't like endless method definitions, but that is
ultimately subject of opinions. mame probably likes endless methods.
I think one issue I see with the proposal here is, if we look at this
suggestion:
:foo = method_body
Then "def" is gone; there is no "define_method" either. I am not sure
this is good. We should keep in mind how people who use ruby - or are
new to ruby - look at syntax. "def" standing for "define a method" is
quite simple to understand, in my opinion. Python also uses "def". I
quite like "def" (I use define_method only programmatically when I
have to define dynamic methods).
Perhaps I am becoming too conservative with old age, but I prefer more
the oldschool ruby variant here - keeping it simple. Just "def".
In regards to omitting "end": I can kind of understand people wanting
to drop "end" just as I can understand people who prefer:
def foo :bar
rather than:
def foo(:bar)
But the saving a few characters should not really be the most compelling
argument. I assume - and perhaps mame can comment - that one advantage
of endless method definition is that it may be easier to write and help
with code golfing somewhat.
Updated by rubyFeedback (robert heiler) 11 months ago
I should also say that I understand sawa's argument too; the
def foo = method_body
really does look a bit weird without "end". My eyes (or rather my
brain) have adapted to assuming a nice "end" being part of a method.
It does not affect me personally, though, as I don't use that
syntax variant. I stick with oldschool "def foo; end".
Updated by nobu (Nobuyoshi Nakada) 11 months ago
sawa (Tsuyoshi Sawada) wrote:
Within Ruby syntax, symbol is naturally used to represent a method name.
Yes, because a symbol is a name.
Not a method.
Updated by matz (Yukihiro Matsumoto) 11 months ago
- Status changed from Open to Rejected
I reject this proposal, because method definitions are tightly coupled with def
keyword under the current syntax. Besides that, :
sigil is for symbols which not always coupled with methods, but identifiers in general. As a result, the proposed new syntax does not help readability nor understandability (from my POV).
Matz.
Updated by duerst (Martin Dürst) 11 months ago
What about using '&', i.e. resulting in &foo = method_body
? '&' is definitely associated with methods/blocks/procs, both in the parameter list of a method definition and in the &:method_name
idiom.