18 April 2006

Aspected Oriented Programming with Rails Engines

I was talking to my co-worker the other day about ruby on rails and some of the benefits of the database wrapper approach versus the database to object mapping approach (which I think is well summarized in this developer works article ) and as a side note, he mentioned that he'd like a framework that did a good job handling cross-cutting concerns (and I think he said JBoss does do this to some degree, but I don't remember how well). Today, after installing rails engines I was looking at the readme and came across this:


Rails Engines are a way of dropping in whole chunks of functionality into your existing application without affecting *any* of your existing code. They could also be described as mini-applications, or vertical application slices - top-to-bottom units which provide full MVC coverage for a certain, specific application function.

This, to me, is finally an example of aspect oriented programming outside the box of logging, security et. al and into an arena of much more diverse problems. And the funny thing is, they never once say the word "aspect" in describing engines (at least in the readme). Woopee! (man, i gotta get a life ;-)

Let me justify my claim with a little more detail. First, a general explanation of AOP with regards to Ruby. Aspect oriented programming works through changing the behavior of your code in some manner that addresses a cross-cutting concern, such as logging, in one form or another. There's code generation, which in the Java world we all know through the heavy use of xdoclet. There's also code weaving, which takes the form of byte code manipulation in Java, a fairly sophisticated task, but doable. With ruby on rails both these forms of AOP are used heavily, but with significantly less struggle. Many of the RoR components use code generation to provide skeleton frameworks and sensible default behaviors, this can be seen right off the bat when you start up your first Rails project and an entire application structure is generated on startup (test framework, make file, properties file, database configuration file, etc). The code weaving is similarly engrained in the framework. For instance, when extending the main email class (ActionMailer) you can simply define methods such as "lateFeeReminder" and then call a method that is generated at runtime "myEmailClass.deliver_lateFeeReminder" and the base class will catch that undeclared method and create a method on the fly (or something to that effect) that allows you to deliver the email that is described in lateFeeReminder. It's the equivalent to byte code weaving in Java, but far easier due to various design aspects of Ruby (interpreted, clean OO).

So back to my point about engines. It'll be a while before I get a feel for how I like working with them, but at least on paper the rails engines are a great way to address concerns such as a login subsystem in a modular, easily overridable way. I'm really hoping to taste some proof in this pudding.

p.s. I know I've left out a lot of references to previous work (smalltalk comes immediately to mind), but I'm trying to be as to the point as possible without glossing over too many details.