Saturday, October 13, 2012

A Refactoring Opportunity Within Rails 3


Rails 3 contains a textbook example of the need for a Replace Method With Method Object refactoring.

Consider this question:

I'm wondering what is the difference between these two methods: ActionView::Helpers::UrlHelper.url_for and ActionController::UrlWriter.url_for?

In addition to two versions of the same method, similar but not identical, the documentation for the ActionView::Helpers method link_to states that link_to accepts the same options which the ActionView::Helpers version of url_for accepts.

(Can you believe newbies find this confusing? What a bunch of morons.)

Anyway, the difference between these two methods with the same name is that the ActionView::Helpers version of url_for accepts a subset of the options which the ActionController::UrlWriter accepts. link_to also accepts that same unnamed subset.

If only there were a mechanism for capturing this pattern of highly similar methods, where one method's possible parameters are a subset of the other method's possible parameters. I can't imagine how such a mechanism might operate, or what it might be called, were it to exist.

Luckily we can discover it by applying the refactoring I mentioned earlier:

Turn the method into its own object so that all the local variables become fields on that object. You can then decompose the method into other methods on the same object.

In other words, whenever the code requires a set of options in more than one place, you can make the code more concise by capturing that set of options in an object. You could, for example, name the object Url or (if you have a fondness for Legend Of Zelda games) Link.

Apologies to the entire open source community, because I'm raising this on my blog rather than participating in the open source development process around Rails, especially since it's entirely possible this is already fixed in Rails 4. However, I've often gotten the impression that specific key members of that process were unpleasant to interact with for me personally, and I'm not interested in participating in a process which requires soliciting their approval. I do however hope that my insight here is useful to someone, somewhere.

Trademarks used here are the property of their respective owners, and appear without permission, but with the full, total, and obvious protection of fair use doctrine in trademark law. The web comic containing these trademarks operates as social commentary on open source culture, represents my opinions and subjective impressions only, operates partly as overstatement for the sake of contrast, should be interpreted with a certain degree of irony, and makes absolutely no claims of factual or historical accuracy (or indeed inaccuracy) whatsoever.