Yehuda Katz recently wrote a post about good old super, probably one of the most underused keywords in Ruby, sadly enough. What can I say, it hit right home. It pretty much nailed what's wrong with alias_method_chain, and pretty much put in words how I felt about it too. It helped to explain why I get a weird feeling in my stomach when I see how plugins like authlogic implement some of their functionality. To sum up: it just feels wrong.

If you don't remember, super is what will call a previously overwritten method in the class chain. The cool thing is that this chain also includes any module that got included in another class or module.

So what does that mean? It means that e.g. ActiveRecord can through out its current approach of hooking things in using alias_method_chain and make life a lot easier by just using super. Neat, huh?

When I wrote the Capistrano extension to extend it to support parallel execution of arbitrary tasks, I started out re-opening the existing classes and modules of Capistrano, and with aliasing some of the existing methods. That was nice as long as I ran e.g. my tests from inside the Capistrano source. When I wanted to move it into a separate project, things got ugly, depending on the order in which my and Capistrano's source files were loaded. They just overwrote each other's methods. No surprise here, but it made me rethink the strategy.

I ended up moving the extension for each class into a separate module, using a different namespace called Extensions, and finally just included the modules in Capistrano's class Configuration, where all the magic happens. Where I referenced overwritten methods I just used super. The code in question now looks like this:

In my opinion a lot nicer to read than the previous version using alias_method_chain. But that's just me. Some libraries prefer to go overboard instead of using what's obvious. I would mention inherited_resource again, but that would be two times in a row.

It's weird that after some time you pretty much rediscover what is still so natural in other object-oriented methods. Using aliases is cool, but I prefer to avoid them, especially when the other option is to use simple inheritance mechanism. After all, Ruby is an object-oriented language.

Tags: ruby

One of the cool things about Ruby is the possibility to make your method's intent more expressive using the question mark or the bang. There's no need to argue about the use of the question mark method, their intent is to ask something, whether it's the the status of an object or if the current weather is suitable for getting out your longboard. Their result will usually be true or false, including nil or not nil.

The other punctuation mark method on the other hand, the bang method, has lead to some confusion as to what its intent really should be. I'm guilty as charged here, a long time I was confused about the difference of using a bang at the end of your method name really means. I guess I should thank David Black for making me (and everyone else) aware of what the difference between a method with a bang and a method without a bang really is.

And here is where the confusion already starts, there being a difference would imply that there need to be two different methods, like in Rails, you have save and you have save!, create and create!, and so on. They usually differ in that the bang version will raise an error, and the normal version will return a value with which it will tell the caller that the call succeeded or failed.

A weird notion arose from that, and I have found in it lots of projects. The notion is that when a method calls save it changes the object, and therefore can have a bang at the end, because it's doing something potentially dangerous. Hold on, saving an object is something dangerous? If you're thinking about it this way, you might as well start banging your methods (pun intended) throughout your project.

A simple example:

def publish!
  self.published_at = Time.now
  save
end

Now, to use the method in your code, we could have something like this:

if !publish!
  # ...do whatever you do in this case
end

I don't know about you but that just looks confusing to me. You're abusing a method whose intent is to signalize that you're doing something potentially dangerous to simply make it "obvious" that your method also saves the object. If you're going down this road, then why not write the name using all uppercase?

def PUBLISH!
  self.published_at = Time.now
  save
end

There, that'll show 'em. If you really want, you can use define_method and give a method name like "PUBLISH!!!".

The Rails extension inherited_resource pushes this a little bit too far, and thank goodness you don't have to use the following way of implementing your RESTful actions:

def destroy
  destroy! do |format|
    format.html { redirect_to projects_url }
  end
end

Here destroy! is an alias for the method destroy in the superclass. The reasoning is that calling super is not readable, and using destroy! gives it a more DSL-like lookie. I just find this style of using bang methods extremely confusing, and the intention is far from being clear. You'd expect destroy! to do something "dangerous", but it's just an ugly way to call the destroy method in the superclass. But the story on super is a totally different story, and material for another blog post.

What you should be doing instead is something along the lines of this:

def publish
  self.published = Time.now
  save
end

def publish!
   publish or raise "Couldn't publish"
end

A bang method should exist together with a non-banged version, or to have a dangerous and a non-dangerous version of your method. Whatever dangerous means depends on the context of your method, but you get the idea.

No need to use if, when someone fancies the bang version, he can just go ahead and use it anywhere. This is how several state machine plugins implement their state changing methods, heck, this is how the Ruby standard library uses it, and this is how you should build your own methods. The bang is not a way to just express that the call will change something in your object, that's what methods on objects usually do, big surprise.

I recommend reading over David Black's post on the issue, it sure gave me a clearer picture. I've written no new bang method since then, because if you think about it, you don't have the case very often where you actually need two versions of the same method. In a library sure, but in your application? Meh. Using non-banged methods in my opinion makes code a lot clearer, especially when you accept the notion that the bang method should only exist in the context of a non-banged version.

Tags: ruby

Apart from the awesome new features for users of the framework, Rails 2.3 got a lot of love on the inside too. It's no secret it's running on Rack now, and that switch made some of the internal code a lot easier on the eyes. They also added a Rails-internal middleware stack, on which some of the framework's functionality builds already.

When you go to the console and enter

ActionController::Dispatcher.middleware

you'll get of all the classes and blocks registered in the stack. Even ActiveRecord hooks into the stack to do minor connection cleanup after a request. Coming from the Java world it's pretty much comparable to the good old Servlet filter (I know they were gross, but still kinda cool), code that gets executed before and/or after each request. An application-wide around filter if you will.

If you look through the code of the classes listed here you'll see one common interface which stems from Rack. They all implement a method called call which gets only one parameter, and an initialize method which gets an application object.

The really cool thing about it is this: Where you had to resign to using the revolting alias_method_chain before, you can now just hook into the request chain wherever you want, without modifying the stack with awkward methods that make debugging a pain in the bum.

Now, where does that make run_later any cooler? Well, it doesn't, but in earlier version I needed to do an awkward thing that only affected development mode, where Rails unloads all classes after each request. run_later runs code in a separate thread, and depending on how long that code runs the classes would be unloaded when they're still accessed from the worker.

In earlier version I turned to, drumroll, alias_method_chain for that, now it's nothing but a simple class that hooks into the internal middleware stack, and delays the request until the worker finishes, or until a certain amount of time has passed (default is 10 seconds). I would argue that you just shouldn't run code taking that long using run_later, so it shouldn't be a major issue. Longer-running tasks like these should be run using a slightly more advanced and reliable mechanism.

Anyway, let's have a look at the code:

The middleware is implemented using a simple stack, unsurprisingly called MiddlewareStack. There you can hook into the chain of classes pretty much wherever you want. I simply append my class at the end, because I definitely want to run the code before ActionController's Reloader class gets to run and unloads the classes. But you can also specify a specific class where you want to hook into the chain, you can even swap existing handlers with your own. Pretty neat stuff. I'd highly recommend playing with it, in some places providing a filter on the middleware level makes more sense than putting the code into a controller-based filter.

Tags: run_later, rails, rack