Transformation

by Steve Yegge

I keep hearing people say they couldn't possibly use Ruby because it lacks automatic refactoring tools. And although it will eventually have some of them, there's a class of automated refactorings that are automatable in Java but not in Ruby. This, people say, is a show-stopper.

I wonder.

What exactly is refactoring? I mean, it's not a word in the dictionary.

Fowler tells us that it's the art and science of turning smelly code into good code, in small, incremental steps. Provably correct, by construction. Algorithms for giving your code a makeover without breaking it in the process.

He gives us a nice taxonomy. He presents some good techniques, especially geared for Java programmers. Some are things we had already figured out and are habitual, and some of them are new.

Some of these "refactoring" techniques are automatable. And many of them are useful in languages other than Java. It seems Fowler and friends have stumbled on something real, something as big as OOP, almost. Or at least they were the first to market it and package it properly. Either way, we know about it now. Thank you, Fowler and friends!

Refactoring is one of the first programming books I've seen that talks about the almost mystical act of writing code. It takes the process, exposes all the insides, revels in it, walks you line by line through oh so many little decisions that affect code quality. These are things most people never talk about. They take them for granted. Most people talk about "architecture". Refactoring talks about the idioms in the code we write every day. Real now-code, not planned someday-code.

It's remarkable, really, that nobody talks about this. They leave all the so-called style choices to the programmer. Refactoring rubs our noses in the implications of our line-by-line style choices. Beautiful.

Discovering Refactoring

Refactoring caught my eye in the bookstore one day in 2002, years after it was published. I hadn't read it because it was published by those UML weenies. I've just never been a fan. It has its uses in database modeling (maybe), but I've never found it useful in class modeling. And I've never cared for the Booch/Jacobsen/etc. crowd's books.

Refactoring is right there, smack in the middle of that weenie series. Every time I see it, my eyes sweep across the cover without a second glance. You know the old saying!

But one wintery day in 2002, I'm in the bookstore, and I pick it up. No real reason. I'm curious. Don't know why. Maybe I'd finally heard the word "refactoring" somewhere. What did it mean? It's not a word in the dictionary.

"Factoring", sure, that's a dictionary word. You can factor numbers, or polynomials. Factoring I know. Don't know why you'd re-do it, though. What's "re"-factoring?

I open the book. It says local variables are the root of all evil. Perhaps not exactly those words, but it's the first discussion I stumble across. Local variables!? I plop down in a squashy armchair, outraged, to read more. I want to know if this guy is actually insane, or merely an idiot.

16 Comments

Dae San Hwang
2006-03-03 02:21:45
Steve, I love your 'opnions', you simply rock! Now I'm heading to amazon! ;)
Jeremy Jones
2006-03-03 05:25:28
Refactoring has been on my "to read" list for a while now. Until reading your post, I didn't realize how desperately I needed it. Now, I'm feeling the same guilt as you describe in the beginning of your post about not having read Refactoring until now. Besides being really informative, this post was beautiful. I hope Refactoring reads as well as this post did!
Pat Eyler
2006-03-03 08:02:01
Nice article. Now I've got to go and reread refactoring to see how much I missed the last time.
Ryan Bates
2006-03-03 09:21:27
Great post! I too discovered Refactoring a few years ago and since then have become a big fan. It is nice to see someone else with the same enthusiasm. Along with the book, Martin Fowler's site is a great resource. Check out his blog and articles, he has a lot of good information there:
http://www.martinfowler.com/
Phil
2006-03-03 13:27:57
This is great. I am in the middle of Fowler's book right now, and I was planning on blogging about it. You beat me to it. It's a good thing, too, because I never could have put it this well.
Rafael de F. Ferreira
2006-03-03 19:23:56
I felt much the same way reading Refactoring. I learned a lot just by looking at the example code (another book that contains similar gems is Kent Beck's Smalltalk Best Practice Patterns).


But that doesn't mean that the discipline of refactoring existing code isn't useful in itslf. It's actually a cornerstone of agile methods, enabling the evolution of an applications's design. The book isn't a catalog of ready-made solutions to code problems, it's a list of small, safe, program transformations. As an evidence, just look at how many rafactorings are the complete opposite of other refactorings (extract method and inline method are obvious examples).


Refatoring isn't done only when the "requirements change" (though they tend to often enough). In an agile process, one whithout a big design up-front, refactoring is done after adding each new feature, in order to always keep the design in top shape. That's how to dynamically conciliate KISS and sound software architecture.


And one word on automated refactorings. I am personally quite fond of them because they help make the process of coding similar to writing prose, in that it's easy to make changes to code while you are with your hands on the keyboard, so to speak.

Russ Olsen
2006-03-04 07:30:36
A similar thing that I hear all the time from folks who won't try Ruby is that they could never give up the little IDE method name completion menus. This is, of course, another thing that is hard or impossible to do in Ruby.


As engineers we should be looking at these questions from a cost/benefit point of view. Simply saying, "I could never live without..." is not engineering. The question is, do we get enough of a productivity gain with Ruby to offset the loss of push button refactoring and method menus? My money is on the clean, expressive language.

Greg
2006-03-04 10:38:42
Ugh. There goes more money for books out of my pocket :(


Great article though. I guess this is one book I can't put off reading anymore.

Dennis Roberts
2006-03-06 13:43:48
Just added to my wish list. Great article.
David Smit
2006-03-06 14:18:53
With Ruby on Rails, the creator of the framework futher forces the porgrammer to write code that doesn't smell by having them write code in certain places (ie Business Rules in the Model) etc. Futhermore in my day job I develop in VB.NET. VS 2003 doen't have any refactoring tools, but I refactor my code every day. All you need is unit tests, a compiler and "Find and Replace" and you can refactor efficiently...
Eman namE
2006-03-06 17:27:20
Hey Steve:


I'm going to preface this by saying that I enjoy your articles. I hope you continue to write more. As a corporate developer, a lot of the stuff you rant about rings a bell.


I'd love to change to language X. The problem is that we have invested lots and lots of money into language J, as have lots and lots of other people who have written lots and lots of libraries that we have found useful. In fact, any new problem domain that we need to tackle usually already has a solution ready for you in problem J. The superior languages (even the ones that have been around for 40+ years) have been staring at the mirror or naval gazing while the inferior languages were out solving problems.


When I bring up your CoolGuy Language X with my managers--who, coincidentally, make the decisions in my company--they say "That sounds nice, and Language X looks really cool, but we made our decision a long time ago." In fact, you'll find that most of the companies out there making real money have taken the same path that my company took. It seems the only way I can be one of the Elite Manbag Carrying CoolGuy Ruby Developers is to create a buzz-word happy startup that replicates the functionality of an already existing client app using web technology (extra 2.0 whuffie if it uses Ajax or RoR).


Aside from language choice, I LOVE my company. We solve fun, hard problems--it just happens that our language of choice is Language J. We may be able to solve them a smidge faster using a different language, but we've been doing Language J so long, that we really don't see Language J when we look at the code anymore--just the particular solution used. And last I checked you can't do embedded development with languages R, P, L and S. There's a huge potential coming up for embedded development. Where are the other languages in this space? Language J is standing on a pile of cellphones just waiting to be knocked off.


Good luck with your crusade--I hope the non-entrenched are listening.

Peter
2006-03-06 22:29:49
Some of the original work in refactoring was done in smalltalk by Don Roberts. He wrote a refactoring browser there. So, if refactoring can be safely handled in a dynamic language like Smalltalk then there is no reason why it could not also be done in Ruby (if people found a need).


Refactoring is defined as a series of semantic-preserving code transformations. Complex ones are built up from simple refactoring primitives. The ability for a language to support refactoring relies and being able to define a set of primitives that can be guaranteed (under some ideal circumstances) to preserve semantics. While this is possible in Ruby there are significantly many circumstances under which primitive refactoring transformations cannot be guaranteed to preserve semantics (meta-programming is a major cause of this pain - but also a major reason that refactoring isn't so desperately needed).


So while refactoring is useful, Ruby isn't suited to it. I suspect that you could use some automated refactoring - but you would have to either bulk up on metadata to describe your application to the tool or otherwise you will have to write your Ruby code in a certain way so the tool can work with it - but then what would be the point of using Ruby.


BTW "Ruby is a butterfly"? Give me a break! It is my favourite language but I wouldn't say it is that special. It has wide ranging abilities - but your average Java programmer will make a dog's breakfast of it (probably worse than they do to Java) - they'll be crying for a refactoring ide (or their workmates will be) no matter what language they work in.


P.S. The insect you describe is a centipede (or millipede, even). Caterpillar's generally only have "true" legs at the front and some variable (depending on family) "prolegs" along their bodies. Pedantic, I know - but..I just .... can't seem .... to .... stop ..... typing!



LaurieCheers
2006-03-07 08:27:27
You just sold an extra 50 copies of that book. :)
Alan Francis
2006-03-09 07:09:33
re: the name. Factoring is like 12 = 1x12, 2x6 or 3x4.


Refactoring is like taking that 1x12 page method and turning it into 2x6 page methods, 4x3 page methods, or ideally a half-dozen classes each with a half-dozen 3 line methods.

Brian
2006-03-11 13:40:46
OK, maybe I'm just a great developer (because I did read Refactoring in 1998 and it stabbed me to the core), but I see the IDE automated refactorings in a completely different light than you. I see them as productivity accelerators that make even more complex "refactorings" possible, because you can so quickly take care of those little, automatable steps in a significant refactoring that might be targeted at addressing the larger issues you enumerated (data modeling, architecture or design patterns). They're not just for lazy "bulldozer" operators that think the only way to live is by pushing mountains of statically typed code around all day by push button.


As an example, just take the act of moving a heavily used public method from one class to another and renaming it in a good sized code base. Without automated refactorings (or types), this results in anywhere from 20 to a few hundred intricate series of editing steps, relying on full text search to ensure you hit all affected code locations. With a good tool that supports move member and rename public member, your editing steps have dropped dramatically. This allows you to focus your attention on higher order problems without losing your train of thought.


When I start programming in dynamically typed languages again, I know I will miss the feeling of being able to cut through all the little editing details of a massive, higher order refactoring as quickly as I can by using keyboard shortcuts in a statically typed IDE. Perhaps this is a reasonable price to pay for all the benefits of switching to Ruby, but I'm unconvinced. Until I am, I'd like to keep my power saw.

Chris
2006-03-29 16:54:30
Wow, as someone new to programming (and self taught) these little gems of information are very important! Keep them comming... (off to Amazon...)