The Compulsive Coder, Episode 5: Extract Method Flow

To be a refactoring wiz in Eclipse or IDEA, you don’t need to memorize dozens of keystrokes. Combined with a few mega-important keys (particularly Ctrl-1, “quick fix”), seven fairly mnemonic keystrokes will supply the bulk of your refactoring muscle. In Eclipse, they happen to be the top seven on the refactoring menu:

refactorMenu

Your version of Eclipse won’t have a key assignment for Extract Constant. It’s one of the rare keys I custom-assign, and K makes sense if you remember enough high school math.

There are about 20 more refactoring menu items in Eclipse, yet I use most of those so infrequently that I don’t find value in trying to memorize the keys to which they’re bound. I use Convert Local Variable to Field often enough, but rather than assign and remember a keystroke, I simply delete the type declaration and use Ctrl-1 to define the field.

I use these “Super Seven” shortcuts frequently throughout a typical coding day. They (a) minimize the amount of typing I do (and subsequently reduce the opportunity for mistakes) and (b) minimize the amount of mouse clicking I do, which is about an order of magnitude slower and worse for my wrist.

I’m amazed at how often I’m able to accomplish some fairly significant refactoring by solely using combinations of the Super Seven.

One such ultra-common sequence is the extract method flow, a bread-and-butter operation for any developer.

Let’s do a bit of extracting against the following test method:

   @Test
   public void answersDaysLateWhenReturnedAfterDueDate() {
      holding = new LibraryHolding(THE_TRIAL, BRANCH_EAST);
      holding.checkOut(TODAY);
      Date threeDaysLate = new Date(holding.dateDue().getTime() + 3 * MS_IN_ONE_DAY);

      int daysLate = holding.checkIn(threeDaysLate, BRANCH_EAST);

      assertThat(daysLate, is(3));
   }

We want to isolate the ugly code to derive threeDaysLate into a helper method, perhaps named addDays. But if we highlight the entire line and simply do Extract Method (Cmd-Option-M), Eclipse doesn’t quite do what we want:

   @Test
   public void answersDaysLateWhenReturnedAfterDueDate() {
      holding = new LibraryHolding(THE_TRIAL, BRANCH_EAST);
      holding.checkOut(TODAY);
      Date threeDaysLate = addDays();

      int daysLate = holding.checkIn(threeDaysLate, BRANCH_EAST);

      assertThat(daysLate, is(3));
   }

   private Date addDays() {
      Date threeDaysLate = new Date(holding.dateDue().getTime() + 3 * MS_IN_ONE_DAY);
      return threeDaysLate;
   }

We want holding.dateDue() and 3 to be arguments to the method. Undo!

A better sequence:

  1. Extract to local variables any expressions we want as arguments.
    1. Highlight holding.dateDue() and press Cmd-Option-L (Extract to Local Variable). Change the variable name to simply date. The result looks like this:
            Date date = holding.dateDue();
            Date threeDaysLate = new Date(date.getTime() + 3 * MS_IN_ONE_DAY);
      
    2. Similarly highlight the 3 and extract it as a local named days:
            Date date = holding.dateDue();
            int days = 3;
            Date threeDaysLate = new Date(date.getTime() + days * MS_IN_ONE_DAY);
      
  2. Extract the method. First select either the whole line, or just select the right-hand side of the assignment to threeDaysLate. Then press Cmd-Option-M. Type in the new method name of addDays. The result:
       @Test
       public void answersDaysLateWhenReturnedAfterDueDate() {
          holding = new LibraryHolding(THE_TRIAL, BRANCH_EAST);
          holding.checkOut(TODAY);
          Date date = holding.dateDue();
          int days = 3;
          Date threeDaysLate = addDays(date, days);
    
          int daysLate = holding.checkIn(threeDaysLate, BRANCH_EAST);
    
          assertThat(daysLate, is(3));
       }
    
       private Date addDays(Date date, int days) {
          Date threeDaysLate = new Date(date.getTime() + days * MS_IN_ONE_DAY);
          return threeDaysLate;
       }
    
  3. Inline the arguments.
    1. Click on (no need to select) either occurrence of the date local variable (either the declaration+assignment, or its use as an argument to addDays). Press Cmd-Option-I (Inline). You’ll receive a confirmation dialog asking whether or not you want to Inline 1 occurrence of local variable ‘date’; simply press enter.
    2. Similarly, click on either occurrence of the days local variable, and press Cmd-Option-I to inline it. The result:
         @Test
         public void answersDaysLateWhenReturnedAfterDueDate() {
            holding = new LibraryHolding(THE_TRIAL, BRANCH_EAST);
            holding.checkOut(TODAY);
            Date threeDaysLate = addDays(holding.dateDue(), 3);
      
            int daysLate = holding.checkIn(threeDaysLate, BRANCH_EAST);
      
            assertThat(daysLate, is(3));
         }
      
         private Date addDays(Date date, int days) {
            Date threeDaysLate = new Date(date.getTime() + days * MS_IN_ONE_DAY);
            return threeDaysLate;
         }
      

      (In addDays, I find the local variable threeDaysLate personally useless, so I also inline it.)

What I love about extracting small abstractions like this is that they open my eyes to additional opportunities to clean things up. It’s now obvious that the method we created belongs elsewhere, perhaps in some sort of date utility class where it broadcasts its existence and thus entices folks to reuse it. What also becomes evident is that the local variable threeDaysLate no longer adds much value. We inline it:

   @Test
   public void answersDaysLateWhenReturnedAfterDueDate() {
      holding = new LibraryHolding(THE_TRIAL, BRANCH_EAST);
      holding.checkOut(TODAY);

      int daysLate = holding.checkIn(addDays(holding.dateDue(), 3), BRANCH_EAST);

      assertThat(daysLate, is(3));
   }

Three steps: extract locals, extract method, inline. No direct typing in the editor. Repeat and ingrain.


Previous Compulsive Coder blog entry: You Create, It Assigns
Next Compulsive Coder blog entry: this Duplication is Killing Me

The Compulsive Coder, Episode 4: You Create, It Assigns

roomba long exposure
Image courtesy Chris Bartle. License.

Some languages are destined to be always overly verbose. One feature I’d hoped for in later versions of Java was implicit typing. In C#, for example, you can declare:

var customer = new Customer("Jose Cañusi");

It’s not too hard for the compiler to figure out that customer is of type Customer.

Java still has no implicit typing. Any time you need a non-specific Customer instance, you need the following code:

Customer customer = new Customer("Elmer Sklue");

I’m out of breath doing all that typing! Well, not really: I didn’t do all that typing. But I’ve suppressed a scream too often pairing with folks who do type the word customer three different times.

We have computers to compute for us. Never mind that the Java language is a cranky old uncle, you at least have a Generation Z development environment if you’re using Eclipse or IDEA.

I’m pretty sure I first saw J.B. Rainsberger demonstrating the following tip at least a dozen years ago.

Type the instantiation (right-hand) side of things first:

new Customer("Anne Teak");

Do not type the left-hand side! Instead, press Cmd-1 (Quick Fix; the corresponding keystroke is Alt-Enter in IDEA). Select Assign statement to new local variable and press enter. If you’re young enough to store away another shortcut, use the slightly more effective Cmd-2-L key combination instead.

Unnecessary typing represents distraction, waste, and risk.


Previous Compulsive Coder blog entry: Typing Isn’t the Bottleneck
Next Compulsive Coder blog entry: Extract Method Flow

The Compulsive Coder, Episode 3: Typing Isn’t the Bottleneck

As Mike Hill says, “the hard part of programming is the thinking,” and not the typing. And yet in this Compulsive Coder blog series, I’m focusing on the very little things, things that might save you as few as milliseconds in some cases:

  • Auto-generated comments that you can simply delete in a quarter second.
  • A color scheme that might trigger slightly faster recognition about something important.
  • And in this post, I’ll implore you to delete lines (like those auto-generated comments) in one keystroke instead of three.

Is all this a waste of time? Shouldn’t we be focusing on bigger, headier things that *are* the bottleneck–such as ways to ensure your code stays clean, so that you don’t waste monstrous amounts of time on code comprehension? Sub-optimization goes against the lean software edict to “optimize the whole.” Why bother?

I’ll offer a few reasons:

  • Less typing ==> fewer opportunities to screw up. Let the computer do the work, it’s rarely wrong! Jeff Bay, via Twitter: “fixing obscure bugs because of obscure f-ing types is a major bottleneck.
  • Wasted time adds up. A mere hundred unnecessary movements across the course of a day add up to half a million across a twenty-year career.
  • RSIs are real, and unnecessary movements similarly add up.
  • Moments you spend on mechanical operations–hunting and clicking, or sequencing together operations–are things that distract from your thought process.

To me, it’s about having the craftsman mentality of caring, more than anything. A craftsman is always seeking better individual approaches to building software. They seek to optimize frequent operations by minimizing the waste involved. They don’t tolerate regular inefficiency.

So, my nit. Real small, real short.

We delete lines often enough in programming. I watch some programmers do so by first navigating to the beginning of the line (if needed), highlighting the text to the end of the line, and then cutting the text (Cmd-X, e.g.). Ridiculous.

In Eclipse, it’s simply Cmd-d (by default). In IDEA, it’s Cmd-Delete. If you have Vrapper (a VIM plugin), it’s dd. One operation, not three.


Previous Compulsive Coder blog entry: Syntax Coloring
Next Compulsive Coder blog entry: You Create, It Assigns

The Compulsive Coder, Episode 2: Syntax Coloring

eclipseColorWheelNote: I understand that not everyone sees the entire spectrum of color. This blog post is focused on those who are able to clearly distinguish color differences. Perhaps my sentiments and suggestions apply to other visual triggers, which as I understand still exist for many of those diagnosed as color blind.

In 1986, my manager broke down and bought me my very first color monitor–a good deal more expensive than a monochrome monitor. I still remember him saying, “What a waste. What do you need those colors for?” I didn’t have much of an answer other than that it was “easier on the eyes.” Mind you, this is in the days where most software was geared for of 25×80 character-mode, green-on-black terminals. I hooked into an HP/3000 minicomputer, and the OS (MPE-III) wasn’t going to cough up anything particularly interesting with respect to colors.

Today, we take color for granted on our phones and other devices, and know how colors play a significant role in garnering attention and triggering reactions.

And yet. At a customer site where developers code using Eclipse, a first glance tells me that virtually all programmers accept the default color scheme provided; no questions asked. Sigh.

What do Eclipse default colors look like? Take a look:

eclipseBlah

Pretty uninteresting, eh? Black, purple, blue. Neither panache nor nuance. Nothing really stands out.

In fact, Eclipse emphasizes the wrong things. Keywords such as public and void and throw are bold and purple, intended to stand out. Yet keywords are often the least interesting thing about a chunk of code; they are likely the thing I need to digest last. Even worthless comments stand out with the Eclipse default color scheme! At least statics are italicized; that seems OK. It’s also good that fields are colored–but unfortunately they are dark blue, which contrasts little with the other elements.

What should stand out in Java code? Fields, certainly. Where a class’s code interacts with fields is a key piece of information. As such, I configure my fields to be bright orange. For most people, the orange fields stand out like sore thumbs. Here’s the same code with my current orange-featuring color scheme:

eclipseColor

Where parameters and local variables are used is also relevant. Being able to track on a specific color for each (gold and green, respectively) can make it easier to track state changes across the body of a method (although the Eclipse feature Mark Occurrences is more useful for tracking a specific variable).

The return keyword isn’t typically very interesting, unless it occurs somewhere other than at the end of a method. No one uses underlining any more, but I’ve found that doing so can help me more quickly spot an early return.

The use of inherited fields–an odd practice, questionable at best (and one that this code doesn’t feature)–really stands out and annoys me, because I’ve made them bright red.

Emphasizing important elements is valuable, but so is de-emphasizing less relevant elements. Comments, too often not to be trusted, are now a light gray, barely visible. On days where I’m particularly affronted with the worthlessness of comments, I make them white.

While my color choices (which I change from time to time) suit me just fine, they might not suit you, however. You and I will disagree on precisely what the “right” things are to emphasize or de-emphasize. That’s ok. The key thing is to make a conscious, informed choice, and to pay attention over time to what the colors tell you about your code.

The world is full of color. Bring your IDE into that world.


Previous Compulsive Coder blog entry: The Stub Comment
Next Compulsive Coder blog entry: Typing Isn’t the Bottleneck

You can find my current color preferences for Eclipse here. You can merge these entries into the file ./.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs in your workspace.

The Compulsive Coder, Episode 1: The Stub Comment

Some things keep coming back, such as facial hair, indigestion, and platform shoes. And for me, Java. I’m once again back in the Java world for a current engagement, and accordingly I’m again working with Eclipse.

The instant I began pairing with folks on Eclipse, my “Felix sense” kicked in, and I became unbearably indignant about the horrible defaults that too many developers simply accept. No one could tolerate more than one Ungar-ism at a time, so in this post I’ll focus on a real simple one:

public Holding findBy(String key) {
   // TODO Auto-generated method stub
   return null;
}
422769556_4094cecb03_m
Image courtesy Adam Engelhart; license

My immediate reaction was probably much like this.

A stub comment! Egads! Why in the world would people pollute their code with stub comments? Coders use their powerful IDE to auto-generate a new, empty method, but then have to waste time picking up and deleting these ugly, useless little stub comments. And horror of horrors, sometimes they don’t–I just saw a screencast where the programmer didn’t even flinch as he created and abandoned a stub comment!

The reason? Maybe it’s the 45-second effort Eclipse requires to turn off these wonderfully useless “auto-generated method stubs.” Or the painfully inadequate system for saving and restoring preferences like this (they’re all over the place), a consideration that crops up whenever you create a new workspace.

Well, I don’t want you to be able to say “I didn’t learn anything from Jeff’s blog.” Let’s start incrementing some Compulsive Coder Principles and Techniques.

Compulsive Code Principle #1
A laziness mentality is acceptable as long as you really do minimize as much work as possible. Creating stubs that need to be deleted isn’t maximally lazy.
Compulsive Coder Technique #1
Open the Eclipse Preferences dialog. Select Java->Code Style->Code Templates. (You can find it quickly by typing code templates and pressing Enter). In the right-hand side of the dialog, select Code->Method body. Click the Edit… button. Change the template’s pattern from:

// ${todo} Auto-generated method stub
${body_statement}

to:

${body_statement}

Click the OK button.

An alternative choice: Change the template to:

throw new UnsupportedOperationException("not yet implemented");

It’s an uglier version of a stub! … but, it’s so ugly it forces you to get rid of it. Where it can be helpful is in keeping you to the red-green-refactor cycle of TDD–the thrown exception will most certainly result in a failing test.

Whichever route you choose, similarly change the Code Template for Constructor body and Catch block body.

I bet you won’t ever miss the auto-generated method stubs!

Stay tuned for more Ungarisms.


Next Compulsive Coder blog entry: Syntax Coloring

Not Giving Up on vi(m)

I wrote this blog as a reaction to reading James McKay’s blog entry, “:q!,” in which he describes abandoning vim. A story familiar to me, but I fortunately never abandoned it for good. I do have to agree that Intellisense and other wonders of modern IDEs make them the preferred environment for things like Java, but I still get a lot of use out of vim.

In the past, I’d be forced to use vim while, say, having to do a small amount of my work on Solaris servers, but then I’d be back on Windows shortly thereafter. I loaded RedHat at home many years ago but it didn’t stick. Then I tried Ubuntu… a couple times, and Un*x finally stuck. Yet I was still only occasionally using vim, which meant I was a perpetual newb, at a “level 1” of vim capability (I’ll sadly call the scale the VCM, or vim capability model).

VCM level 1 is the ability to get in and out of the tool and do basic editing (search, page forward, change/replace text, occasional use of the dot operator, etc.). I remember that I too thought the only way to delete many lines was via count-based commands (e.g., 10d). At VCM level 1, vim beeps at you a lot, and you don’t understand why people swear by it.

What changed things was a result of being forced into having to hit vim on a daily basis for an extended period of time. I had the opportunity to work with Tim Ottinger a bit, and we would pair from time to time. Tim is the author of a great article on vim, “Use vim Like a Pro.” I won’t mention pairing after this paragraph, but I will say that without the ability to pair with someone at a higher VCM level, I might never have advanced much from my level 1 proficiency.

I’m making up the VCM based on my history, of course, but it might just work for others, too. VCM level 2 is marked by use of these critical elements of vim:

  • regular use of the dot operator
  • use of hjkl for cursor movement
  • ability to manage buffers, registers, and split windows
  • ability to visually mark code
  • regular use of f and t in combination with other commands; use of other context-based movement commands
  • use of ctrl-n for auto completion
  • awareness and occasional use of macros
  • occasional use of help facility to learn something new
  • regular (no pun intended) use of regex
  • use of ctags to aid code navigation

Reaching level 2 was important: At level 1, I simply thought vim was a frustrating, not-very-powerful tool. At level 2, I am fairly effective when editing, and faster at many tasks than most people in their GUI editors. I also see that there is much more to learn and master.

Tim is probably at VCM level 4: mastery of most, if not all, of vim’s features. I suppose that marks Level 3 as when you have ingrained all the major facilities (i.e. most everything that Tim covers in Use vim Like a Pro), are trying to ingrain something new on a regular basis (I’ve now habituated the use of ~ to toggle case, for example), have considerably customized your .vimrc, and are making an active attempt to do everything in the most efficient way possible. I am getting into level 3 now, but I haven’t used vim heavily in a while.

During my fortunate opportunities to learn vim from Tim, I discovered there were a few things about vim that he didn’t know. Shocker! It’s an extensive tool, but I guess what that means is that there’s a VCM level 5. Let’s define that as mastering VCM Level 4 plus everything that Tim doesn’t know now.

Roaming Keymap Profiles

When pairing, I often learn little shortcuts and tips that I might never pick up otherwise (even though I’m the compulsive sort who comprehensively reads things like the entire list of commands, just to find some new trick). I try to impart at least as many tips as I take on. Pairing makes it happen, as there’s little better than to have an insistent partner who keeps reminding you to “just hit Ctrl-Alt-v” (introduce variable in IDEA, an essential refactoring). In the absence of a pair, IDEA’s Key Promoter plugin helps a bit.

As someone who pairs across many teams, I regularly encounter different IDEs and programmer editors. Usually teams standardize on one tool, but not long ago I worked in a C++ team where there were 8, count ’em, 8 different editors in play. Currently I am working with a team where some people are piloting Eclipse, while the rest of the team uses IDEA.

Give me a few minutes and I can ramp up OK, but switching IDEs throughout the day will make just about anyone feel stupid. Ctrl-d, duplicate line in IDEA. Switch to Eclipse, oops, Ctrl-d, I just deleted a line. Nope, it’s Alt-Ctrl-Down to duplicate a line. Move a line up, Ctrl-Shift-Up in IDEA. Wait, though, I can’t remember the Eclipse corollary, but I do have muscle memory, and so I now have to go try it… wait for me… it’s Alt-Up. And so on.

Why don’t I just change the keymaps so that they’re more in synch with each other? Or why not use, say, a vi keymap everywhere? The problem is that I’m pairing with others, and so the simplest thing is to go along with the IDE defaults (which is what the predominance of programmers uses).

On my wish list and/or backlog of things to work on, I’d love it if IDEs would support a standardized roaming keymap protocol, as well as a simple mechanism for toggling profiles. I would be able to specify a URL from which the IDE would download my profile. From there on, a simple keystroke would toggle from the active keymap profile to mine and vice versa, in order to expedite pairing.

I’ve been hoping to see more support in IDEs for things like TDD and pairing. It’s coming, albeit slowly. Any plugin fanatics out there who want to give this one a go?

NetBeans

I was very excited to start using Infinitest once again. But as things seem to go with me, I ended up moving on to something else that dominated my mindshare–in this case, a new project where I am using NetBeans. Why NetBeans? Because someone set up the project to use Maven, and all I’ve heard is that NetBeans is magical when it comes to integrating with Maven (and Eclipse, not so much).

As I would expect, both Maven and Maven support in NetBeans are really nice as long as they’re working well. But Maven seems to adhere to the 80/20 rule. It’s great 80% of the time, up until you have to do something a little out of the ordinary, or when things aren’t working like they’re supposed to. Then the numbers reverse–you spend 80% of your time trying to work on the remaining 20%. In the case of Maven, I’m struggling with getting coverage reports against multiple modules, and it’s also presenting me with a defect (operator error?) where NetBeans reports half the Maven modules as “badly formed Maven projects.” Google searches, and assistance from others with more Maven experience than me, have not been very fruitful.

This is the third time I’ve used Maven, and I’m warming up to it more each time, but it’s still been a frustration. Part of frustration is always lack of knowledge, particularly around the behind-the-scenes workings that you need to know when you hit the 20% esoterica. Thanks to those who have helped!

On the other hand, this is also the third time I’ve used NetBeans heavily. I’m not really warming to it much. Granted, part of my disappointment with NetBeans is the same problem. The best way to learn not to hate something is to pair with someone who knows it well, and I’ve not been able to get much pairing time.

Other than the Maven support, NetBeans seems much weaker than Eclipse. It’s slower (e.g. a Ctrl-O to search for types takes many seconds to return class names, compared to Eclipse’s Ctrl-Shift-t which is almost immediate). It’s flakier (e.g. half the time, ctrl-F6 to run a test pops up its JUnit GUI, the other half the time I see only the console output; also, the formatting mechanism appears to be broken). It seems to be the last of the three main Java IDEs for which people write plugins (e.g. Infinitest is only available for Eclipse and IDEA, not NetBeans). And it’s just missing key important things (e.g. there is no inline method refactoring until NetBeans 7.0).

I can live without every last bell and whistle. But it’s always disappointing to see other people whistle in cool little ways, like Kerievsky’s nice trick with inline method, and not get to play along.

Comments:

There is no way to read the Kerievsky trick without becoming a member of the Yahoo group. It would be helpful to cut and paste the content.
# posted by Anonymous Anonymous : 5/08/2010 12:59:00 AM
Aug 5, 2009, from Joshua K:

One of the refactoring strategies I defined and use quite a bit is called Parallel Change. You put new behavior next to old behavior (wherever it is) and then do a Gradual Cutover from old to new. When you’re done cutting
over to the new code, you need to get rid of the old code.

Say you’ve got some old method that was called in 10 places in a class. The new code, which had been placed under each of the 10 calls to the old code, is now doing the real work. You don’t need the old method and the calls to it.

In the past, I would delete the method, then follow the chain of red marks to delete each call to the old method. That was before a smart student pointed out a better way:

* Delete the body of the old method
* Inline the old method – effectively inlining “nothing”

That approach is much faster and far more satisfying.

Is this something folks already do? It had not occurred to me to use inline in that way to delete code.

This does go along with an observation I’ve made that the better you get at refactoring, the more you use the Inline Method refactoring.
posted by Blogger Jeff L. : 5/10/2010 07:44:00 AM

Less Refactoring

If you could have only one refactoring, which would it be? Which refactoring could you least afford to give up?

To me the obvious answer is the rename refactoring. It’s an activity that I do very frequently. In fact, the way I code is dependent upon my ability to do a rapid rename.

I try to follow Uncle Bob’s mantra “never be blocked” at even the smallest granularities. I won’t stew for more than a few seconds to derive a name for a class, field, method, or other identifier. Instead, I type. If my brain is really frozen, I’ll surge forward by typing an “x” or the word “something.” No worries–I usually think of a better name shortly thereafter. I then do a ctrl-1/rename, type the new name, press enter, and Eclipse completes the job for me very safely and quickly.

The name isn’t final at that point. I’ll continue to update an identifier’s name as my understanding of what it represents gets refined (or changes).

Recently I committed myself to working more in-depth with Groovy. I’m happy with its improved simplicity, consistency, and expressiveness over the tedium that is Java. As always, I spent a while using Groovy’s bare-bones tools (groovyc, groovyConsole, etc.) so that I understood them enough to survive if I had to. Done enough of that! Now I’m looking to my productivity experience by introducing an IDE, so I downloaded and installed the Groovy plugin for Eclipse.

Harumph, and that’s even after ignoring (a) a couple bizarre errors that I received because I hadn’t forced a clean and (b) the obtuseness of the exceptions. No, the big harumph is that there are no ctrl-1 or refactoring options anywhere to be found. I’ve heard IDEA is better (and hope to try it out here soon), but as I understand, the rename challenge will never be completely resolved: safe rename refactorings require type information. You can provide that in Groovy, but figure on most developers not bothering.

And for now, the Eclipse plugin isn’t even trying. I created a private, typed field–something for which a refactoring operation could be very safe–but now I can’t change its name without resorting to search/replace. The fact that I may need to discard my newer programming style of “continual rename” makes me feel dirty.

Even with some forethought, programmers will always choose some names that end up less than ideal. And since developers are notorious for not changing things that might break, the poor names will remain as long as the IDE can’t do it safely. Maintenance costs will be higher.

The main point of my post is that after years of using a strongly-typed language, I am now resisting languages like Groovy and Ruby to an extent. Not because I’m worried about the defects that could happen at runtime that wouldn’t otherwise-my use of TDD generally means that’s not an issue. Instead, my complaint is about lack of productivity, and worse, the decreased amount of refactoring that will likely result.

The question is, do benefits accruing from the increased simplification of the code outweigh the negatives of more difficult refactoring?

Comments:

[Full disclosure: I may have an interview with you soon, so I may just be sucking up here with my comment.]

I’ve collected a few links and thoughts on refactoring languages like Ruby at my blogki, and sometimes share similar concerns.

Some counter-arguments I believe I’ve heard on this topic … and may or may not agree with:

– Ruby doesn’t require as many refactorings as a language like Java does. It’s easier to morph your designs without outside aide. Much like the GoF Design Patterns is mostly moot in Smalltalk — you don’t need a design pattern for something that is second nature.

– Refactoring was invented in Smalltalk … why worry about refactoring tools for Ruby? They’ll come.

– … (well, I’m tapped out. I guess I didn’t need a list here.)

I like your post, though. I’m very fond of my friend “Call Hierarchy” in Eclipse — esp. when working through a mess of code. It’s faster to analyze call paths then to try and make some changes and then wait for a test suite run to tell me if I went wrong (obviously, both are valuable, though). Of course, the codebase should probably make more use of coding to interfaces and not have such a long running test suite … but … such is life.

Ramble off.

I know first hand how anal you can be about refactoring, so I understand what you’re talking about. I’ve just been able to introduce Groovy into our environment and have been running into a lot of the limitations of the Eclipse Groovy support. I’ve been pleasantly surprised at IntelliJ’s Groovy support, which includes refactoring. It’s not a perfect solution, as I still prefer Eclipse for my “normal” development, but it’s a decent stopgap until Eclipse’s Groovy support becomes more first class.

Atom