No returns

— December 15, 2009 at 19:57 PST


Chris Wanstrath makes a good point about an ugly way to initialize a variable, but I don't agree that an explicit return is the best style to use.

The original ugly:

def logger
  unless @logger
    @logger = Logger.new(STDOUT)
    @logger.level = Logger::WARN
  end
  @logger
end

Chris' improvement:

def logger
  return @logger if defined? @logger
  @logger = Logger.new(STDOUT)
  @logger.level = Logger::WARN
  @logger
end

I prefer a functional style:

def logger
  @logger || begin
    @logger = Logger.new(STDOUT)
    @logger.level = Logger::WARN
    @logger
  end
end

This is actually slightly awkward. I'd usually do @logger ||=, but that's hard to do gracefully since here you have to combine a few statements to create the new logger. A better constructor or a #level method that returned self would be so much nicer. A small refactoring seems a bit more readable.

def logger
  @logger ||= default_logger
end

def default_logger
  logger = Logger.new(STDOUT)
  logger.level = Logger::WARN
  logger
end

And if you really like functional style and are a fan of the K combinator:

def logger
  @logger ||= Logger.new(STDOUT).tap {|l| l.level = Logger::WARN}
end

I am almost always opposed to using an explicit return in Ruby code. Whenever I see one I cringe. You can sometimes make a case for one as a top guard in a medium-sized method, but here's where I invoke the slippery-slope argument. It's too easy for those things to snowball into a handful of return statements, and then someday you'll have to wonder if they have to be in that order or not. And when your method gets long enough, you can easily miss that there was a return at the top and mess up a refactoring; using an if/then/else makes it clearer and harder to miss.

By the way, using if defined? @logger the way Chris does is not the same thing as if @logger.

>> defined?(@logger)
=> nil
>> @logger
=> nil
>> @logger = nil
=> nil
>> defined?(@logger)
=> "instance-variable"

If you're trying to make sure @logger is not nil, defined? is unlikely to be the way you want to test the variable was initialized. Be careful out there, kids...

UPDATE: Oh awesome, it turns out that Logger.new takes a 2nd arg, the level. So this could all be done with:

def logger
  @logger ||= Logger.new(STDOUT, Logger::WARN)
end

Just pretend this whole thing was about some other class where this actually mattered.

8 commentsruby

RubyConf 2009 Lightning Talks

— November 20, 2009 at 11:00 PST


Last night it was my great pleasure to host the Lightning Talks session at RubyConf 2009. We had an amazing series of 20 talks that took just over 2 hours. The tech gremlins seemed to be off drinking somewhere and none of the presentations failed.

Here's a list of all the speakers and links to their stuff.

2 commentsconference, lightning talks, rubyconf

RubyConf Schedule

— November 12, 2009 at 11:05 PST


The RubyConf 2009 schedule was just posted. As a public service, I have fixed it to be readable and to use, you know, hyperlinks and stuff. Enjoy.

http://hasmanythrough.com/rubyconf2009/schedule.html

(Apparently my planning for GoGaRuCo 2010 has me thinking it's 2010 already. Fixed the year. Sorry about that. Sigh.)

0 commentsconference, rubyconf

Pair programming isn't right for all projects

— September 23, 2009 at 23:48 PDT


My hat's off to Obie Fernandez for his recent article 10 Reasons Pair Programming Is Not For the Masses. I don't actually agree that only the elite are cut out for pair programming, but I do think he's on target with his list of obstacles to effective pairing.

There's another axis to consider for fit, however, and that's the suitability of the work itself for pair programming. I don't mean the product domain or the kind of application being written, but rather the technology and tools used to build it.

I started pair programming when I was a freshman in college. My CS10 lab section had 20 students and only 10 computers, so we had to pair up. No one told us anything about how to pair; we just did it. It wasn't really a big deal since students are used to helping each other with class assignments. I think the pairing was valuable for learning, but there was a problem. The problem was Pascal. Specifically, the length of time spent compiling the code every time we made a change. We'd write some code, then fire up the compiler and play Pascal (the game of seeing how many dots you can generate before you get a compiler error). Compiling took a long time, anywhere from 5 to 20 minutes, depending on how big the program was. So what do you do with your pair during that time?

There are all sorts of reasons we hate long wait times during development, whether from compiling, running tests, deployment, or whatever. While it can be nice to take an enforced break now and then, the disruption to flow is a significant obstacle to productivity and quality of work. A five minute interrupt to your flow is murder to your mindset and caustic to your collaborative bond.

After college I worked at Xerox, programming in Smalltalk on a team of about 8 developers. We tended to pair a fair amount, maybe a quarter to half of our time on average. But at other places I worked, we paired a lot less. I'm sure some of that was cultural, but I think a lot of it was because of the technology. Programming in the Smalltalk environment really good for keeping the flow going. Do some coding in a method and save the code, and a second or three later you can see the results. This made pairing so much easier because we could keep our focus on the coding. It's hard enough to keep the pair in a good mode when things are going well, but to have to stop for a few minutes every few minutes adds too much frustration, and the easiest place to direct that frustration is onto your pair.

So if your project is not amenable to a rapid, incremental development cycle, it's going to be a lot harder to keep people pairing on it. I guess that leaves two options. You can punt on pairing, or you can fix the technology so that you get the fast development cycle necessary for maintaining flow. Can you guess which one is going to be better for you?

4 commentsagile, pair programming

Circle of death

— September 3, 2009 at 22:15 PDT


debt circle

43 comments — [none]

Archives