There's More Than One Way To Do It
Some languages, like Python, have fostered a culture of writing code in a single way. As The Zen of Python puts it: "There should be one-- and preferably only one --obvious way to do it."
Ruby, on the other hand, embraces the idea of multiple ways to write the same thing. An attitude inherited from Perl, where "There’s More Than One Way To Do It" (TMTOWTDI or "tim-tow-tiddy") is a famous slogan of the language. The underlying philosophy is that programmers should be free to choose the style that best suits their context, needs and preferences.
This philosophy is evident in many aspects of Ruby. Its flexible syntax, for example, has given rise to a wide variety of coding styles. Some styles are so particular that one can guess their origin just by looking at the code. Like this one:
def assert_includes collection, obj, msg = nil
msg = message(msg) {
"Expected #{mu_pp collection} to include #{mu_pp obj}"
}
assert_operator collection, :include?, obj, msg
end
def assert_instance_of cls, obj, msg = nil
msg = message(msg) {
"Expected #{mu_pp obj} to be an instance of #{cls}, not #{obj.class}"
}
assert obj.instance_of?(cls), msg
end
This is an example of "Seattle style" Ruby, taken from the Minitest library, authored by Seattle-based Ruby programmer Ryan Davis. It is characterized by avoiding the use of parentheses in method definitions and calls (when possible). It also doesn't shy away from using { ... } for multi-line blocks, which are otherwise more commonly done with do ... end style.
Another recognizable style is:
class Account::JoinCodesController < ApplicationController
before_action :ensure_admin, only: %i[ update destroy ]
def show
end
def edit
end
def update
# ...
end
private
def join_code_params
params.expect account_join_code: [ :usage_limit ]
end
end
This is an example of "Basecamp style", taken from Basecamp's Fizzy codebase. The main giveaway here is the egregious use of spaces inside brackets, but also the indentation of the private section. This is now the default style for new Rails codebases, though funnily enough their generated linting configuration includes a commented out section to stop it with the brackets madness 😂
So is this principle actually a good thing if it leads to such wildly different codebases? Wouldn't we be better off if newcomers to Ruby wouldn't have to break a sweat trying to figure out whether they should put parentheses around their method calls or not?
Well, obviously there is a tradeoff at play here. But perhaps Groove Armada said it best:
"If everybody looked the same, we'd get tired of looking at each other".
Tomorrow we'll look at some more examples of the tim-tow-tiddy principle in action, but in the context of the Ruby standard library.