« Beyond Javas: Chapter 6. Ruby in the Rough | Main | Chapter 7: Ruby on Rails »

Transformation: Ruby Smells

I keep hearing people say they couldn’t possibly use Ruby because it lacks automatic refactoring tools.


Marting Fowler tells us that Refactoring is 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.




I keep hearing people say they couldn’t possibly use Ruby because it lacks automatic refactoring tools.


Marting Fowler tells us that Refactoring is 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.


Some of these “refactoring” techniques are automatable. It seems Fowler and friends have stumbled on something real, something as big as OOP, almost. Thank you, Fowler and friends!


Refactoring is one of the first programming books 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. 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. This guy sounds like Kevin Reynen (Sidewalk Theory), I love him!


Discovering Refactoring



“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.


Horror sets in: he’s right. His explanation makes chilling sense. One of my cherished programming practices — caching intermediate values in local variables, as an inline performance optimization — is clearly demonstrated, before my very eyes in the squashy armchair, to be Evil. It explains why I have certain methods in my code base that keep growing and growing, and for reasons I’ve never been quite able to grok, the methods are unsplittable.


These big methods, they’re the Bad Places. The areas of the code base where I loathe to tread. Dark caves that grow more evil every time I visit them. Because add functionality I must, but the locals have threaded their way impenetrably through each function, spiderwebs that catch me and hold me.


The book shows me why they’re unsplittable, then gives me axes to split them. Sharp and precise tools. And the techniques make sense, right then and there.


I move on. Turning pages faster, now. Interested.


The book next tells me: don’t comment my code. Insanity again! But once again, his explanation makes sense. I resolve to stop writing one-line comments, and to start making more descriptive function and parameter names.


But the book is a landmark, and it made me a better programmer overnight. How often does that happen?



[Having found that others he surveyed haven't read it he confesses.] I’m safe. I can study it, use it, not worry that everyone will know how foolish my code has been.


Refactoring Today



Everyone knows about Refactoring nowadays, because IDEs now have all of the automatable refactorings from the book, and a few extras to boot.


But despite its overnight popularity, most engineers have read Fowler’s book, not even a few chapters of it.


Reprise



I keep hearing people say they couldn’t possibly use Ruby because it lacks automatic refactoring tools. This, people say, is a show-stopper.


I wonder.


I read Fowler. I absorbed it. It’s the art and science of taking smelly code and turning it into better code, in small provable steps.


But he taught us something else, didn’t he?


Oh, but you wouldn’t know what that thing is, if you haven’t read his book. Have you? All of it? No skimming? C’mon now. Admit it. You skimmed.


Here’s the deal: to show us the paths from bad code to good, Fowler had to show us bad code. He showed us examples of what it looks like, and explained why it’s bad. He gave us a set of warning indicators and even called them “Code Smells”.


How did that code get smelly in the first place?


Well, we optimized prematurely. We stored too many intermediate values, for fear of recomputing them. We didn’t write small functions, for fear of virtual method-call overhead. We made bloated class heirarchies for the imagined benefits of reuse...


We were making dozens, hundreds of little mistakes that added up to some pretty smelly code. The book catalogued our mistakes, gave them names, elevated them to First-Class Mistakes.


[Understanding the basics of refactoring] you know what bad code smells like, and you know how it got that way. You’ve learned how to avoid writing it.


At what point did automated refactoring tools become the focus? The book’s original focus was about design, with tools for recovery. Now the focus is all on recovery, and specifically on the automatable subset of recovery techniques.


The implicit assumption here is that bad code just happens, inevitably. His book wasn’t just a catalog of 100-odd specific refactorings. It also presented themes. Once you get the core ideas, you can invent your own refactorings, and identify new code smells.


And now you know better how to write the code better the first time around.


Refactoring is zoomed way in. It’s focused on how you personally wrote this or that class or method, down at the level where you were making choices about local variables, control-flow constructs, and other micro-design decisions.


Refactoring can’t really be discussed in a vacuum; it’s interdependent with other modern development ideas, including “don’t repeat yourself”, “once and only once”, unit testing, and others.


Push-button Productivity




Automated code-refactoring tools work on big set of entities — objects, methods, names, anything patterned. All nearly identical. You have to change them all in a coordinated way, like a caterpillar’s crawl, moving all the legs or lines this way or that.


How did our code get that way to begin with? We wrote it badly. Refactoring to the rescue. Good design may be a lost cause, but we can recover, because we have automated servants to go fix all those little segments for us. They never get tired, and all we have to do is push buttons.


Well then. How could you possibly live without automated refactoring tools? How else could you coordinate the caterpillar-like motions of all Java’s identical tiny legs, its thousands of similar parts?


I’ll tell you how:


Ruby is a butterfly.