Reason #131 • May 11th, 2026

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:

Ruby
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:

Ruby
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?

Ruby
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 🕺

Reason #132 ?