Optional parentheses
One of the fundamental design principles of Ruby is that it should be a natural and intuitive language to read and write. To that end, Ruby allows us to omit parentheses both when declaring and invoking methods:
def greet(name)
"Hello, #{name}!"
end
greet("Alice") # => "Hello, Alice!"
greet "Bob" # => "Hello, Bob!"
# Parenthesis-less method definitions are almost never seen in
# the wild, except if the code is written in Seattle:
def greet name
"Hello from Seattle, #{name}!"
end
greet "Charlie" # => "Hello from Seattle, Charlie!"
I've seen this optionality cause quite a bit of frustration for newcomers to Ruby. However, it is what enables many of the DSL (Domain-Specific Language) style APIs which Ruby is famous for.
Take this ActiveRecord model definition for example:
class User < ApplicationRecord
include SomeModule
has_many :posts
has_many :comments
validates_presence_of :name
validates_uniqueness_of :email
end
Wouldn't it be awful if we had to wrap all those method calls in parentheses?
class User < ApplicationRecord
include(SomeModule)
has_many(:posts)
has_many(:comments)
validates_presence_of(:name)
validates_uniqueness_of(:email)
end
The declarative vibe is completely lost, and some of us will have to go lie down in a dark room for a while after looking at that.
My condolences!
History
Ruby has had optional parentheses since the very beginning. The inspiration likely came from Perl, which also allows optional parentheses for method calls (albeit inconsistently).
It's worth noting that the list of known influences on Ruby's design includes both languages without parentheses like Smalltalk and the most parentheses-heavy language of them all, Lisp. So Ruby does logically end up in the happy medium with its optional parentheses, allowing us to cosplay in either direction as we please 🕺