---
title: Basic Readability
teaser:
tags: web,ruby
author: Jon Yurek
published_on: 2007-04-18
---

Is this simple code? It's an example from the docs on `Symbol#to_proc`:

    people.select(&:manager?).collect(&:salary)

It's certainly readable. It's elegant and expressive. But making it possible
employs a number of fairly advanced topics relating to automatic conversion of
method arguments as well as the ability to extend existing classes—not easy, and
not something that someone new to the language would think of. Hell, it's not
something that people familiar with the language would necessarily think of. But
when that was pointed out as a new addition to ActiveSupport, rubyists all over
the world joined each other in a collective "Why didn't I think of that?"

Even if you don't know _how_ or _why_ it works, you can tell what it's doing.
But is it simple?

We recently got into a bit of a row here in the office over the idea that for
code to be optimally maintainable, anyone who has a passing familiarity with the
concepts of a language should be able to understand what's being done. The
intended result being that if anyone can understand it, then the logic is simple
enough for anyone to hold in their head and therefore refactor without
distorting its goal. To this end, it was recommended that all advanced features
of the language should be shunned, because, by definition, novices wouldn't be
able to understand what's going on. Going to the logical extreme of the
argument, learning how to use those advanced features is a waste of time, since
code written using them is unmaintainable.

The other side of the argument was that given the use of only the standard
tools, you will only ever make standard code, not great code; it's argument
being that if you can create great code that is elegant and reads well, then you
have both made your code easy to maintain by virtue of being readable, and you
have made your code powerful and expressive by virtue of using features that
wouldn't be available had you kept to "standard" techniques. This comes at the
cost of potentially writing code that no one else can understand or maintain.

I think `Symbol#to_proc` is a good focal point of contention for this debate.
The actual definition of it is in
[`vendor/rails/activesupport/lib/active_support/core_ext/symbol.rb`][to-proc]
(which, for the sake of reference, I'm posting here).

[to-proc]: http://api.rubyonrails.com/classes/Symbol.html#M000007

```ruby
class Symbol
  def to_proc
    Proc.new { |*args| args.shift.__send__(self, *args) }
  end
end
```

The standard techniques side does not like it, because a novice does not
understand why it works. The other side likes it because it allows
expressiveness in a small package, and the novice can still understand _what_
even if they don't understand _how_. The actual code required, given basic code
formatting, is 5 lines (and a `require` if it's in a different file). But the
knowledge required behind it is much higher: You need to know that prefixing the
final argument of a method call with an ampersand will tell Ruby to try to
convert it to a block using the `to_proc` method, that you can open existing
(and even standard) classes to add methods, and that you can call methods on
objects without knowing the methods' names (via `send`). It is a very elegant
piece of code, to be sure, but does it have any place in the code you write on a
day to day basis?

Even if you consider the code at the beginning of the article to be simple, an
important question is whether or not the cost of having simple code is justified
by having a complex, even tricky, bit of code elsewhere that allows the
simplicity in the first place.
