Sunday November 23, 2008

Merb: less magic, more engineering

As discussed in "How I arrived at Ruby", I've become a big fan of Ruby. As soon as I realized that I really, really wanted to work in Ruby (a couple of years ago, at this writing), I started looking for ways to use the language professionally. (Hobby programming is lots of fun, but it doesn't pay the bills. :-)

I found that Ruby is being used in a number of contexts (eg, administrative scripts, Cocoa and Google SketchUp programming). However, Ruby on Rails was clearly the high-order bit (or maybe byte :-), in terms of industry buzz, contract and job opportunities, etc. So, I got some books and dived in.


My introduction to Rails was quite a bit rougher than my introduction to Ruby. As I had heard, Rails (coupled with its many add-ons) provides a very powerful toolkit for creating database-driven web sites. However, the Rails suite has a steep, long, and constantly growing learning curve. A Rails wizard can create web sites very quickly, but becoming a Rails wizard can take a substantial amount of time and effort.

Rails is best suited to "green field" application scenarios, where the database can be designed to match the task at hand. Getting it to work with an existing database setup may involve some ugliness. No surprises here; DHH is very clear that Rails is "opinionated software".

Rails also involves a lot of magic, which the early books only explained in terms of "how to" (as opposed to "what is"). I'm a person who wants to understand how things fit together, so this increased the difficulty and frustration level of my learning process.

As long as I stayed on the path, things tended to work well. Doing anything unusual, however, could lead to a lot of unwanted stress. Yes, I can read the code and reverse engineer things, but why should I have to do this? Better system documentation (architecture, design, and interfaces) would have helped a lot.


My misgivings about Rails were poorly defined, however, until I attended Yehuda Katz's recent presentation on Merb. Basically, what I had been missing in Rails was focused, disciplined engineering. This is not to say that Rails is poorly engineered; indeed, many parts of the system are excellent. However, the Merb developers have improved on Rails in a number of respects:
  • Defined APIs

    Merb has defined APIs, with stability guarantees, for both application developers and plugin writers. So, I can write code that uses the public Merb 1.0 API and have some faith that it will continue to work with any Merb 1.x release. When Merb 2.0 emerges, I can expect conversion assistance and a similar set of guarantees.

    In support of this, each method has a tag (eg, @plugin, @private, @public) that declares its intended visibility and controls its handling by the documentation system. Although it's possible to use a @private method in an application or plugin, the need to do so indicates a report-worthy bug (ie, limitation) in Merb's design.

  • Discoverability

    One of the great benefits of Open Source software is the fact that it's possible to dive into the supporting libraries (etc), discover what's going on, and if need be, make a modification. Fortunately, Merb is designed to be much more discoverable and hackable than Rails.

    Merb applications are expected to override the Merb core at times, so the Merb developers work hard to make this as safe and easy as possible. For example, metaprogramming and method nesting ("methods all the way down") are consciously minimized in the Merb framework. This makes the code easier to understand, less brittle and gotcha-ridden, etc.

    Merb also has (and follows!) standards for documenting its methods, classes, etc. Each method in the Merb framework has a header block that details its purpose, parameters, return values, visibility, exception handling, etc. An application developer might have to study a method to understand its implementation, but not to simply determine its purpose!

  • Flexibility

    Merb is far less opinionated than Rails about many things. It supports a choice of object-relational mapping frameworks, JavaScript libraries, template languages, etc. This gives the application developer far more flexibility in creating a system to meet the problem at hand.

    At the same time, the Merb developers realize that some guidance may be useful. So, they provide a collection of "best practices" (the "Engine Yard Stack") to help application developers get started on the right foot. The goal is to handle the first 80% for the developer, while constraining the last 20% as little as possible.

  • Magic

    One of Merb's design goals is to reduce the amount of "magic" (ie, implicit interactions). At the same time, many beneficial uses of "magic" are still present. So, for example, the controller has to request that an appropriate view be rendered, but display will automagically render all authorized MIME types.

    This reduction of "spooky action at a distance" is not possible in quantum physics, but it's an achievable (and laudable) goal in programming frameworks. As Yehuda Katz puts it, display is OK because you have to invoke something to make the magic happen; magic rendering is less OK because it happens without you doing anything.

  • Minimalism

    Because Merb has a minimalist approach, its code base is significantly smaller and simpler than the Rails equivalent. Adding in Merb's explicit interactions, detailed documentation, and visibility distinctions, an application programmer can have a reasonable expectation of being able to understand what's actually going on.

  • Modularity

    The Merb distribution is set up as a base release and a buffet of "plugins" and "slices". Plugins extend the functionality of the core, providing features such as object-relational mapping. Slices act much like Rails Engines; they are miniature applications (including assets, MVC stacks, namespaces, and routes) which can be incorporated into a Merb app. A slice can be used "as is", seasoned to taste (eg, monkey-patched), etc.

    Merb distributes both plugins and slices as RubyGems, so it can take advantage of a well-developed toolkit for managing packages, versions, etc. Merb also leans on powerful tools such as Git, Haml, jQuery, Rack, Rake, and RSpec. In summary, Merb is well suited to the "composition" of web applications.

  • Performance

    For a large class of programming problems, performance isn't a big issue. However, public-facing web sites are not part of this class. Yes, you can throw more hardware at the problem, but that is wasteful of energy, hardware, space, etc. So, performance matters...

    All else being equal, a Merb application will run much faster and use far less memory than its Rails counterpart. Even if performance is not an overriding consideration in your situation, it's nice to know that you're not wasting cycles.

Roll-out Plan

Merb is a bit of a moving target at this writing. The 1.0 release defines a stable set of APIs, so many more developers can be expected to start writing production applications. This process will surely uncover problems in both the APIs and the implementation. At the same time, the Merb developers have lots of things they want to try out after 1.0.

So, the developers have announced a roll-out plan for Merb releases. Implementation problems that are discovered in 1.0 will be handled by a series of 1.0.x releases. Production applications that need a stable platform should stay on the 1.0.x series, at least until 2.0 is released and vetted.

Experimental applications should track the 1.x series, any of which may introduce API extensions. However, all 1.x releases are expected to pass the 1.0 test suite. So, code written for 1.0 should continue to work on any 1.x release. Problems found in a 1.x release will be addressed in a following 1.x release; few 1.x.y releases are expected.

The 2.0 release (ETA Summer 2009) will package up a set of successful and stable changes to the implementation and API. Presuming that this roll-out strategy has worked well, the same pattern will be followed for the 2.x releases. If not, I can only assume that accommodations will be made.

Merb: less magic, more engineering in Computers , Technology - posted at Sun, 23 Nov, 11:02 Pacific | «e» | TrackBack


Great article, thanks a lot.

- Matt

I think you are spot on with your misgivings about Rails. I am sticking with it, but your points about its large code base, ever growing learning curve, and instability ring true.

Rails has a split personality. One side promises great productivity and a pragmatic framework with which to earn a living by knocking out CRUD applications.

The second personality originates from coders (not business people) whose main goal is to enjoy programming, and woe betide anybody who has not got the time, energy, or brains to keep up. (This is not pragmatic at all !)

The two sides are incompatible. Worse, I don't see how the culture of Merb can be merged into that of Rails. It's an attitude thing.

Post a comment

Note: All comments are subject to approval. Spam will be deleted before anyone ever sees it. Excessive use of URLs may cause comments to be auto-junked. You have been warned.

Any posted comments will be viewable by all visitors. Please try to stay relevant ;-) If you simply want to say something to me, please send me email.