Home > Articles > Programming > Ruby

Refactoring in Ruby: An Interview with Bill Wake and Kevin Rutherford

Russ Olsen talks with Bill Wake and Kevin Rutherford about their book, Refactoring in Ruby. Bill and Kevin reveal what is different about refactoring Ruby code, the state of agile processes in the software industry and what the mountain dulcimer and medical sociology have in common.

Russ Olsen is the author of Design Patterns in Ruby.

Like this article? We recommend

Like this article? We recommend

Russ Olsen: First let me congratulate the two of you on the publication of your book, Refactoring in Ruby. Refactoring is one of those-two sided software engineering terms: It has a very specific technical meaning, but people also tend to use it informally as a synonym for 'rewrite'. So help me understand the difference: What's the difference between refactoring code and simply rewriting it?

Kevin Rutherford: Refactoring involves carrying out a series of numerous small well-understood steps, each of which leaves the code's behavior unchanged. So refactoring is like crossing a river using stepping-stones: you can go a long way one step at a time, you can turn back and re-trace your steps at any time, and you never get wet.

Bill Wake: It can be a question of scale. If you're returning the system to stability every few minutes, you may be refactoring. If the system is torn apart for days, weeks, months, you're not refactoring. If the system has new features, you may have been refactoring along the way, but there was more than just that going on.

There's a lot of value in knowing your system performs the same before and after; watering down the term loses a useful distinction.

Russ: How is refactoring different in Ruby than in one of the more traditional languages like Java? Are there particular refactorings that are more difficult? Easier?

Kevin: The mechanics of a particular refactoring in Java, say, can make use of the safety provided by compile-time checks; indeed some of the steps in Martin Fowler's original Refactoring book use compiler errors as a to-do list. But in Ruby there's no static checking, so one degree of safety is missing. For that reason, it's even more essential to have very good test coverage when refactoring Ruby.

Another interesting aspect of dynamic languages has to do with code smells. In a language like Java the code is littered with type clues, which hint at overuse of primitives, for example. These clues aren't available in Ruby, and it can therefore be much harder to carry out enough static analysis to determine whether a given code smell is present.

Bill: A language as dynamic as Ruby does have challenges for tool providers. There will be situations where the tool is making a weaker promise than it would in an equivalent Java situation. (It's not hopeless; refactoring tools originated in Smalltalk, another dynamic language facing similar issues.)

Russ: There are a lot of features of Ruby that simply do not exist in other widely used programming languages—things like open classes and metaprogramming. Did you come across any new refactorings, ones that are specific to Ruby?

Bill: Our focus is on smells more than the mechanics of refactorings. (You can see Fields et al for those.) We described some new smells, notably Dynamic Code Generation and Procedural Code, specifically for Ruby's more unusual features.

A lot of code has more workaday issues before you get to these more exotic aspects of Ruby.

Kevin: We discovered that the details of many code smells differ depending on language features, although the overall forces of Good Design (communicates intent, contains no duplication, contains no unnecessary stuff) remain constant. For example, Fowler's original listing of code smells includes Incomplete Library Class; we've expanded this to Incomplete Library Module and included some discussion of when it is safe to open up a module that someone else wrote.

Russ: So if refactoring is all about chasing out code smells, how do you know when enough is enough? When do you stop refactoring?

Bill: Sometimes you get that sense of "ah" when things click into place.

Most times, I'm refactoring in the context of developing something, and I try to pay attention to what's "on track" for that. I'm happy to refactor the code I'm touching, or the code it touches, but I watch out when I go beyond that. (Cleanup may be needed there, but I only want to go there mindfully.)

Kevin: My guiding light is Kent Beck's rules of Simple Design: The code must first be correct (as defined by tests); then it should be a clear statement of the design (what J.B.Rainsberger calls "no bad names"); then it should contain no duplication (of text, of ideas, or of responsibility); and finally it must be the smallest code that meets all of the above. It's time to stop refactoring when the code makes a reasonable stab at meeting those goals, and when any further changes would add no further benefit. There's a lot more on this topic in Chapter 2 of our book.

Russ: If you each could change one thing in Ruby, something that would make refactoring easier or otherwise improve the language, what would that be?

Kevin: I'd like to see more work done towards some kind of standardized abstract syntax tree for parsed Ruby code, to help make it easier to write refactoring tools, style checkers and other code analysis tools. My other major gripe is the relative inconsistency of parts of the core API (why doesn't Dir[] return an array of File objects, for example?); rough edges like that mean we all write the same code to compensate, which in turn makes refactoring somewhat harder..

Bill: Ruby libraries tend to take a "union" approach to adding terms. "Length or size? Let's add both. Map or collect? Let's add both." This may be helpful for some adopters, but it creates APIs that are wider than necessary, and it makes it harder to spot duplication textually.

Russ: It's hard to say the word refactoring without also saying 'agile'. Do you think that software development in general is really becoming more agile, or is it something we are just talking about without really acting on?

Bill: It's hard for me as an individual to get a read on it. I'm a consultant for Industrial Logic, so most people I work with either are agile or want to be. Techniques such as refactoring, continuous integration, and TDD are penetrating into more places, but we have a long way to go, and those aren't the whole of agile or what it offers. I see more interest in craft, XP-style approaches, and learning; that's good for the long run.

Kevin: As an industry, we definitely know more now about how to develop "good" software than we did fifteen or twenty years ago, both in terms of technical practices and organizationally. But I still find that TDD and "simple design" are widely misunderstood; and far too few organizations involve a coach to help them improve.

Russ: Kevin, you are the lead developer for reek, the popular tool for detecting code smells in Ruby programs. Did you learn anything in the process of writing the book that made you rethink something you did in reek?

Kevin: I actually did it for the opposite reason: The heart of the book is Part II, in which we examine over forty code smells in great detail, looking at how to detect them, how they might arise in real code, what problems they each cause, how to fix them, and what might happen to code when the smell is removed. I began writing reek because I wanted to look at how easy or hard it is to detect certain code smells in Ruby, so that we could provide clear guidance to our readers. I learned a lot about what can happen when you push code to the limit, eradicating smells that few human eyes (noses?) detect; much of that experience is reflected in the descriptions of the smells and in the book's exercises -- and much of it involves appreciation of the varying effects of change on different parts of the code.

Russ: As someone who can barely stand myself when I am writing, I am curious as to how you worked out the process of writing a book together. Were there lessons from developing software in groups that you could apply to your joint writing project? Did you consciously refactor the book?

Kevin: We had Bill's excellent Java Refactoring Workbook as a starting-point, so in a sense we were refactoring an existing book. We converted the text to LaTeX, broke it into sections and stored it in over a hundred text files in a Subversion repository, so that we could both work on different sections without conflicting. During the most intense few months we had weekly stand-up meetings over Skype (amazingly, Bill and I have never met). I think it's a great tribute to Bill's tolerance and skill as a coach that he managed to work calmly and for long periods with someone so intense, driven and opinionated as me!

Bill: Kevin's definitely too kind; you can see why he was easy to work with.

I think we were closer to rewriting than refactoring--we had some new things to say! We had some global changes to make; we just divided them up. We tended to have temporary ownership by chapter; one would own it, the other would polish it after it was stable.

Subversion was a win, as was being able to build the book when we wanted. LaTeX was OK (except for tables!) but I'm open to better tools for shared writing.

Russ: What do you guys do when you are not off writing books?

Bill: I'm a consultant, as I mentioned. Outside of work, I've recently taken up mountain dulcimer. It'll be a while before I perform in public, but I'm having fun learning. I've always got little software or writing projects going, and my web site (xp123.com).

Kevin: I work full-time as a freelance agile coach (www.kevinrutherford.co.uk), and I have three young kids who occupy the remainder of my time.

Russ: So with the book complete, what's next?

Kevin: I have a pact with my wife; first I got to obsess over a book for two years, now it's her turn. Donna begins work on her Ph.D. in Medical Sociology this month, so I can have fun being a proper dad and home-builder again. (Don't tell her, but I also plan to do some more work on Ruby quality tools, and maybe some writing on certain aspects of "simple design".)

Bill: "Analysis" has been on my mind a lot; I'd like to write something about that. I'm also interested in writing something outside the software arena; I'm still chasing ideas there.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020