Ruby vs. Java Myth #2: Ruby feature X makes code unmaintainable

Welcome to the second installment. You can catch the first myth here.

Ruby includes a variety of features that lead to compact, expressive code, e.g. open classes, dynamic evaluation, soft encapsulation rules, easy metaprogramming, and closures. These features demo well, but developers who have not used them fear that they will lead to unmaintainable code.

In reality, Ruby's powerful features make code more maintainable, when used correctly. (Learning to use these features correctly will be the subject of another myth.)

What makes code maintainable? You should be able to easily

  • Understand the overall design of an application or module
  • Find code you are looking for
  • Read the code
  • Make changes to the code
  • Verify that the changes work

Given these criteria, how do Java and Ruby stack up? I believe that the responsibility for maintainable code lies 80% with the programmer, and only 20% language and tools. With that caveat in mind, let's look at each point in turn.

Understand overall design. Advantage: Neither. In my experience, no language is very helpful here. Good abstractions help. Java and Ruby share many abstractions in common: implementation inheritance, classes, polymorphism, encapsulation, etc. The Java world has much better support for navigating these abstractions, via IDEs such as IntelliJ IDEA. On the other hand, Ruby has some useful constructs that Java lacks. Mixins help keep code more organized. Ruby makes it easy to create DSLs that accurately reflect and document your design.

Find the code you are looking for. Advantage: Java. Java's IDE support wins hands down. (It is worth remembering that many of us adopted Java when this IDE support was nonexistent.)

Read the code. Advantage: Ruby. Now we are down to the level of individual classes and methods. At this level, Ruby code is easier to keep DRY, and therefore easier to read. If you do not believe that Ruby is easier to keep DRY, then read about the Blub paradox.

Change the code. Advantage: Ruby. When you change code, you often move past the uses anticipated by the original author. At this point the compiler gets in your way, because some of the original author's assumptions need to be bent or broken. Change is much easier in a dynamic language.

Verify that the changes work. Advantage: Neither. If you are serious about quality, then you need to test. Manual testing is infeasible, so you need automated testing: unit tests, acceptance tests, continuous integration, the works. Both Java and Ruby provide good support for these.

Neither Ruby nor Java can make your code maintainable. I propose that we replace the old myth (feature X makes code unmaintainable) with no myth at all. If your primary argument for choosing a language is a presumption that language X will cause people to write maintainable code, then you have either a bad presumption, or the wrong people. You would be better off to pick a language at random, and change either the presumption or the people.

Get In Touch