When it comes to building long-lived, maintainable systems, it’s my position that we should strive to write code that differs from the expectations of the reader (the next programmer) in ways that are meaningful. Put more plainly: try to write “normal” code, and only write “weird” code when you’re doing something unusual.
Depending on the community or language you’re writing, this might be a more or less of problematic suggestion. When a language has documented and well defined styles and norms, you can point to them as the idiomatic way of doing things.
Unfortunately for Rubyists, we have many different styles we can point to as “normal”. I won’t claim to understand exactly why we ended up in this situation, but I think our language lends itself well to it. Let’s look at some big ways some styles differ:
Foo.bar(3)
or Foo.bar 3
and both are functionally identical.def foo bar
instead of def foo(bar)
. Again, these are functionally identical.{
/}
) or do
/end
. Again, these are functionally the same, but some popular styles advocate using them in different situations.class Foo::Bar
or in the nested fashion, as:
module Foo
class Bar
end
end
This is by no means an exhaustive list, merely a few good examples of style decisions that Rubyists are force to make on aday to day basis, if they aren’t already dictated by style guide or automated tool.
Even our automated tools have some issues. The most popular tool, Rubocop, provides default settings that do not reflect the style of Ruby written on any project I’ve ever worked on. Because of this, many teams adopt hundreds of lines of configuration for the tool in an attempt to enforce a style that the team considers more “normal”.
A new tool has even recently emerged called StandardRB which seeks pare down and reconfigure Rubocop’s settings and provide a zero-configuration tool that enforces a style that can be generally accepted by the community.
Such tools exist for other language (for example, prettier for JavaScript), but many of those languages feature much simpler syntaxes that lend well to this. Languages like Elm, Rust, and Go actually ship with their own official formatters that enforce very specific code-styles. In these languages you could omit all the optional whitespace and trust that the formatter will snap your code into the offical style of the language.
Ruby won’t ever have one of these heavy-duty formatters. This isn’t a flaw in the language; the variety in Ruby’s syntax allows Rubyists to write more expressive code. The Rubyists I’ve spoken with enjoy the variety, control, and even implicit conventions that allows us to communicate more richly through our code.