Browsing the blog archives for September, 2009.

Usul’s Words Have Power, Part 1: Refactor

work safe

Words have power. For those who practice the Weirding Way (from Dune), this is to be taken for granted. Some agree with the Humpty Dumpty (Through the Looking Class Ch. 6) and a word means exactly what they choose it to mean. But, to counter that point, I offer the following description of my dinner last night; “Proxy Flu quickly house Cabbage’s”. Communication is based on a shared understanding, so let’s share. More correctly, I’m going to share with you what I mean. Then we’ll communicate.

People are still confusing Refactor with Redesign.

As we bound through the local community and the wider internet, it is all too common we hear something like, “We have no time to Refactor, It’s a nice to have, but we can’t”. I have also heard, “We give our team one month a year to refactor and do stuff for us.” I humbly submit, “You’re doing it wrong!” I understand that’s an inflammatory statement. I intend to back up those words, so bear with me through a metaphor.

I’m baking a cake. I was making a five course meal for the in-laws when they suggest that a cake would be nice. I really want to get that cake out and onto their plates, and I want to impress them. I look around the kitchen and realize that I’ve just used my last big bowl making the batter. I need to frost the cake, but I need the big bowl to make the icing. I reach for the nearest bowls I can find, four small bowls of different sizes. Now I have to make several small batches of icing to get the same amount. I have risks. My calculations of the ingredient proportions could be wrong. I can underestimate the size of the bowls. I can combine the ingredients in an inconsistent manner. Worse, it take four times as long to make the icing, because the time it takes to make icing isn’t directly related to the amount you make.

That was one option. Another option is to stop everything and clean all the dishes at once. But I would very literally be starving my in-laws. The last plan is to clean the big bowl and maybe a beater and spatula I could use, but only those that I need. Then, when I’ve finished, I could clean up the dishes I used for the cake. That is Refactoring.

What is implied by the statement, “we don’t have time,” is that they want to stop and clean everything. That is a redesign.

In pondering why the misunderstanding exists, I can only blame myself and other proponents (not really, but I’m making a point about misunderstandings). When talking about Refactoring, we usually start with a complete program and make changes. We don’t have a choice because we want to isolate the Refactoring act for pedagogical reasons. But it tells only half the story. A half that gives the impression this is a post-development effort. In addition, when talking about the power of small steps adding up we mention it’s possible to redesign from a series of Refactorings. But the point to drive home in that situation is lost. The code never stops being developed. We do this to express the notion that if you clean the dishes as you go, you’ll never have to wash all the dishes in the house.

When do we Refactor? At one extreme, the TDD side, you Refactor after every passing test. On the other extreme I should get my feature working, check in, Refactor and check-in again. I don’t wait until the end of the quarter. That is a Redesign, not Refactoring.

Let’s lay down one more time why we Refactor. Our first pass at solving a problem is littered and strewn with a confused jumble of ideas. Refactoring gives us a chance to solidify our abstractions, improve readability, increase reuse, manage dependencies, increase testability, and clarify APIs.

How do you start in an existing project? Clean the code you’re currently using. Not to make it perfect, but to reduce the risks of spaghetti code. If you start with a pile of dirty dishes and clean only what you need, you won’t clean all the dishes, but you will clean the ones you use most often, and they will always be clean when you need them. You didn’t mean to write bad code, you just forgot to wash the dishes.

4 Comments

C# Lies. But You Knew That, Right?

work safe

Mark posted a question about using the MenuItemBy method on White’s MenuBar class from ruby. But there’s a problem. While the examples show C# code being used with two parameters as below, it is a lie. That method uses the params keyword, which means the rest of the CLR sees that as an array. You’re just lucky in C#. The literal translation of the code below to IronRuby will fail. 2 arguments for 1. Because it expects a typed array, not multiple parameters.

  win.MenuBar.MenuItemsBy(SearchCriteria.ByText("Task"), SearchCriteria.ByText("New"))

So, we can just wrap our criteria objects in a ruby array and pass them in? Nope. Not in 0.9, and not without some meta magic. We need a Core.UIItems.Finders.SearchCriteria[], so we’ll get one by detouring through a generic list. Oh! this is a great time to notice that CLR classes use the [] operator to return parameterized instances of themselves, like the C# <type> syntax. Here’s what my cucumber step definition looks like for creating a new task via a menu.

When "I click Task -> New" do
  l = System::Collections::Generic::List[Core::UIItems::Finders::SearchCriteria].new
  l.add(Core::UIItems::Finders::SearchCriteria.by_text("Task"))
  l.add(Core::UIItems::Finders::SearchCriteria.by_text("New"))
  @win.menu_bar.menu_item_by( l.ToArray ).click
end

This works. I admit it ain’t the prettiest, but it is expanded for demonstration purposes. Yeah, that’s it. I’m kinda rushing to get some stuff done (and posting for breakfast), so I’d like to revisit this later and clean it up with metaprogramming. Maybe next month?

I also want to note something. I thought including namespaces was so damn cool, but White and WPF use similar names and I’m not sure ruby’s modules are doing the isolation I want, so I’m avoiding it until I need it. Also something else to look into.

No Comments

Disposable Code

work safe

I took a quick look at some WaitN examples this morning to see if there was anything I needed to fear when doing an example of WaitN in IronRuby. Then I saw it. IDisposable. More correctly, a using statement. What would that look like in IronRuby?

module System::IDisposable
  def self.use_these(*disposers, &block)
    block.call(*disposers)
    disposers.each {|d| d.dispose}
  end
  def using(&block)
    block.call(self)
    self.dispose
  end
end

class DisposableHero
  include System::IDisposable
  attr :name
  def initialize(name = "Jed")
    @name = name
  end
  def do_something_to(other)
    puts "#{@name} washes a car for #{other.name}"
  end
  def do_something
    puts "#{@name} doing something"
  end
  def dispose
    puts "#{@name} is being disposed"      
  end
end

DisposableHero.new.using do |d|
  d.do_something
end

System::IDisposable.use_these(DisposableHero.new("Tony"), DisposableHero.new("Ryan")) do |t, r|
  t.do_something_to(r)
end

I added a using method to any IDisposable object that handles scoping. In addition, I added a multi-object disposing use_these block so I don’t have to nest my using blocks. It’s not perfect, but for five minutes of thinking, it’s not too bad.

2 Comments

It’s like Sports Center, but Not.

work safe

Do you know how many RBIs have been hit against Cal Ripkin? How many times was a Manning sacked by a running back last year?

To put it a different way, who has the most Oscars for cinematography in a tv series?

I’m pretty sure those questions make no sense. I’m not passing judgment on sports fans, or movie buffs. I choose to spend my time doing other things. This crystallized while I was talking with Ryan. Some people have different information acquisition profiles. A few months back I saw an interview from RailsConf of Tim Ferriss, the author of the four-hour work week. He mentioned he had stopped pro-actively acquiring information because by the he needed it, he’d forgotten it. If we couple this with the acknowledgement that we can’t learn everything, what’s the best way to gain knowledge? The thesis of the interview was “just in time knowledge.”

The Internet, and your local library, make this possible. With a network of friends, it’s not a bad idea. But there is a catch. How do you know if there is something out there to know?

Recently, a coworker asked me about sending data over a modem. I couldn’t help him solve his problem, but I gave him enough to start looking. But in a sea of data, where can I find a library to tell me the frequency of a sound? Which XML library should I use? How do I know to use MVVM or IOC? Where do I start?

I’ll let you figure that out. We started to identify three patterns of acquisition; Infovore, tasker, and opportunist. These patterns depend on a combination of the person and the area of interest.

An infovore collects information for the sake of information. It’s a news hound. It’s a super fan. It’s how I approach programming. It is my hobby, but it might not be yours.

A tasker starts researching around the edges of their task. Think an informed patient. Researching cars when you need a new ride. Looking at testing frameworks when you’re a developer tester.

An opportunist only learns what they need when they need it. I’m so here with car repair. I’ve been known to watch a soccer game on TV, but I have no idea who’s playing this week, or when.

The interesting thing about this is that different people fit different profiles for different topics. A fantasy football player is likely either an infovore or a tasker regarding their team. But most of us are taskers or opportunists when it comes to health insurance.

Let’s look at three RPG players. One spends time on the Wizards boards tweaking min-max builds all weekend. Another looks at the books when it’s time for build a character or level, but still enjoys the game. The last loves hanging out with his friends, but still has to ask (though not as often) what does he roll for that again? Who’s fun is wrong-bad? I can’t tell you that.

I think the interesting part is to realize the categories of interest in our lives and determine what are acquisition profile is in those categories. Then, accordingly, determine if we’re okay with that.

1 Comment

Crouching Donny, Iron Cucumber – An Experiment in Functional Testing

work safe

I accidentally agreed to give a talk later this month. The subject is IronRuby and it’s application in the .NET ecosystem. Seems simple enough. So, to jazz things up, I want to have a host of demo applications. This is about one.

A while back, I posted an article with an example of using IronRuby and the White framework. In it, I appear to have made a promise.

I’ll get to Cucumber. I’ll publish examples. I promise.

Continue Reading »

1 Comment