Jun 27

I like to keep up with developer blogs, so I definitely read/watch Railscasts, The Intridea Blog, Hacker News, Paul Graham, Joel Spolsky and the like.

However, I get a lot of utility out of following the blogs of lesser known people I know or have worked with. If you haven’t checked them out already, please visit my peeps on their blogs:

  • Fred Wilson: Ok. Not really one of my peeps, per se, but a smart guy who I respect and read daily.
  • Sean Cook: If you know or have worked with me, it’s likely that you know or have worked with Sean. He’s starting to ramp up the content on his site with technical stuff, but the music stuff if worth a visit.
  • Brendan Lim: A smart guy that used to work on my team. One of the two brains behind Yappd.com.
  • Theo Nguyen-Cao: Theo is a versatile, quiet hacker who says more in print than in person, but is worth listening to in either situation.
  • Brent Collier: The other of the two brains behind Yappd.com.
  • Laurie Ruettimann: I haven’t met her in person, but her HR blog makes so much sense that nobody in the startup world can afford to not read it.

Enjoy.

Jun 21

This week was one of the toughest I’ve had to go through at work. Here’s a completely random set of things that have made me smile in the last 24 hours.

Fruity Cheerios. - It’s like eating Froot Loops, but they’re called Cheerios. All of the pleasure with none of the guilt.

Yo Gabba Gabba! - It’s a slightly ridiculous, but amusing kids show. Today, I curled up with my kids on the couch and ate fruity cheerios with them while watching the “Party In My Tummy” episdoe.

Punk Rock HR - Laurie Ruettimann used to work for Big HR, but after becoming unemployed a year ago, she started writing a blog about opting out of the corporate rat race. It contains such gems as “The Punk Rock Employee Handbook” and some refreshing quips like:

- Team building is for suckers.
- Office Speak is for Suckers.
- “You’re not cool and ironic. Trust me. You’re not.”

I think she likes to call people “suckers”. But in any case: read her stuff. Very amusing.

Jun 16

Fred WIlson makes a great point today about howblog comments can be as important as blog posts themselves. In this post, he says:

I want to be able to easily reblog onto my front page any and all great comments in a format that shows that they are comments and a link to the post the comment is from. I want to be able to easily reblog the comments I make on other blogs to my blog. I want services like techmeme and friendfeed to understand that comments are as important as blog posts (friendfeed is on its way with disqus and intensedebate integration). And I want commenters to have their own blogs that are simply aggregations of the comments they leave on the web. That’s happening too, here’s my disqus page.

Great stuff. I agree. I often paraphrase my comment back onto my blog as a new post. And, my disqus page is almost a blog on its own. However, I’d really like to have the option in either my blog software or on my disqus page to “Reblog this comment as a new post” on my main blog page.

The Disqus API should make this kinda trivial to support in most blog software. But how do we get the maintainers of Blogger, WordPress, Typo, and the dozen other blog providers to support it? I can tell you from experience that getting it into Typo as a patch will take more time than writing the code itself.

So how about a javascript badge that will do it? That shouldn’t be too hard. Who’s working on it?

Jun 09

I’ve released the typo theme you see right now via GitHub. I’m probably going to migrate to Mephisto in the next week or so, so this theme will go out of support, but I’ll maintain the repository and honor any pull-requests if you want to patch it.

Jun 08

The new Rails routing has nice support for nested reources. And, I think it handles just enough nesting. Any more support, and it’s possible to go overboard and write ugly code.

For example, here is what Rails now supports for nested routing syntax:

1
2
3
4
5
  # Simple parent child association
  map.resources :user, :has_many => :posts
 
  # A parent with many types of children
  map.resources :posts, :has_many => [:comments, :trackbacks, :pingbacks ]

Nice. That is prefectly terse and descriptive, without being too clever.

There has been some debate and consternation over why a complicated multi-nested resource can’t be set up this way. For example, if I am building a project management tool, why can’t I do this?

1
2
map.resources :projects, 
  :has_many => [ :releases,  :milestones => [:tasks, {:features => :tasks}] } ]

That is, a project has many releases AND milestones, and in turn milestones have many tasks and features. And, features can also have tasks.

That’s complicated, and too much cleveness to jam into one statement. I think Rails 2.0.2 / 2.1 has it right in making you write that routing rule like this:

1
2
3
4
5
6
7
8
9
  map.resources :projects do |project|
    project.resources :releases
    project.resources :milestones do |milestone| 
      milestone.resources :tasks
      milestone.resources :features do |feature|
        feature.resources :tasks
      end
    end
  end

I hear a crowd of people clamoring for the uber-terse syntax outlined in the second listing. I think that’s a bad idea. It encourages hard-to-follow, obfuscated code.

When you have to do something complicated, it’s worth taking a few extra lines to make it clear to the next programmer.

Jun 06

Sorry for the outage on this blog yesterday. My hosting provider upgraded to Rails 2.1, and I had cleverly forgotten to:

bash# rake freeze:rails:gems

If this happens to you, and you make the unfortunate mistake of trying to instead update Typo to Rails 2.1 using:

bash# rake rails:update

You’ll be in even worse trouble, unless you’re prepared to do a lot of fixing:

bash# Pete$ script/server
./script/../config/boot.rb:45:in `require': no such file to load -- ./script/../config/../vendor/rails/railties/lib/initializer (LoadError)
	from ./script/../config/boot.rb:45:in `load_initializer'
	from ./script/../config/boot.rb:38:in `run'
	from ./script/../config/boot.rb:11:in `boot!'
	from ./script/../config/boot.rb:109
	from script/server:2:in `require'
	from script/server:2

Your best bet? Revert from source control and freeze Typo in your dev environment. If you’re stuck without source control or a dev environment, let me know and I’ll talk walk you through the alternate fix.

May 26

Since I seem to be on a “Comment” and “Terseness” rant, I’d like to point out that I dislike block comments for everything but RDoc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
x ||= ["0"]
=begin
  this is a block comment
  It's good for auto-generated documentation
  , I suppose. 
 
  x.push("1")
 
  But that line of code above might be mistaken 
  for something that executes, if you're not using
  a good IDE with colorization. 
 
=end
puts x.inspect          # ["0"].... NOT ["0","1"]

It’s harder to make that mistake when the code looks like this:

1
2
3
4
5
6
7
8
9
10
x ||= ["0"]
#  this is not a block comment
#
#  x.push("1")
#
#  Now that line of code above shouldn't be mistaken 
#  for something that executes, even if you're not using
#  a good IDE with colorization. 
 
puts x.inspect          # ["0"], just like you'd expect

Given that just about every IDE out there allows you to select a bunch of text and comment it out en-masse, I think the second method works better.

Hopefully, Peter Cooper will forgive me for taking issue with so many of his Ruby Tricks. Most of them are REALLY REALLY GOOD.

May 26

In my post about clever code vs. terse code, I showed some distaste for code that attempts to put a bunch of logical statements on one line. I have a particular coding prejudice that lines of code should be short from left-to-right, if at all possible.

The reason? I like sidebar comments.

Maybe this is my showing my age. Back in the day, we didn’t have widescreen MacBook Pro laptops that could display 600 characters across the screen. (And we liked it! While walking uphill both ways in the snow to school…) Between 17″ CRT monitors and the IDE, I was lucky to get 100 characters across.

So instead of writing long lines of code, I prefer to use a couple extra lines and simplify each discrete statement. Then I will sometimes put comments (aligned with each other) out in the right margin that map to my pseudo-code (which is usually just in my head….I don’t actually write much pseudo-code in Ruby).

For example:

1
2
3
4
5
6
7
8
# Spawn a set of threads to process the queue
1.upto(threadcount) do |thread_id|
  threads << Thread.new(thread_id) do |i| # Each thread
    until @queue.empty?() do                    # grabs an item from the queue
      yield(thread_id, @queue.deq())            # and yields it to the block
    end
  end
end

Some people call this “code smell.” The meaning, I guess, is that if I have to write comments that outline what the code does, the code must be too complicated.

I beg to differ.

Imagine for a moment that you are a fresh-out-of-college programmer, and you open up my codebase to maintain it. You find this:

1
2
# Spawn a set of threads and process the queue all on one line
1.upto(threadcount) { |thread_id| threads << Thread.new(thread_id) { |i| yield(thread_id, @queue.deq()) until @queue.empty?  } }

You might run away screaming after a few dozen lines like that. I sure would. Smaller lines with comments make it easier to follow. And I think sticking them out on the right margin where they don’t interrupt the flow of code makes it easier to ignore them if you’re an experienced programmer who doesn’t need them.

May 26

In 21 Ruby Tricks You Should Be Using In Your Own Code, Peter Cooper outlines some really useful best practices that programmers could benefit from. However, I think that there’s a tendency to over-obfuscate code from time to time in the Ruby world.

I like terse code. I like beautiful code. But I dislike tricky code. For example, let’s look at two tricks Peter Cooper outlines in his post:

Trick #7: Cut down on local variable definitions.

1
2
3
4
5
6
7
 
# Cooper says do this: 
(z ||= []) << 'test'
 
# Instead of this: 
z ||= []
z << "test"

Counting whitespace characters, Cooper’s version of the code is 20 characters long. The second version of the code is 20 characters long. Personally I find the second version easier to read.

Trick #9: 9 - Use ‘and’ and ‘or’ to group operations for single liners.

1
2
3
4
5
6
7
8
9
10
11
# Cooper likes this:
queue = []
%w{hello x world}.each do |word|
  queue << word and puts "Added to queue" unless word.length <  2
end
puts queue.inspect
 
# Output:
#   Added to queue
#   Added to queue
#   [”hello”, “world”]

Hm. While I think this does terse up the code by grouping statements that do a single logical operation onto one line, I think it’s still easier to read this way:

1
2
3
4
5
6
7
8
9
# I like this:
queue = []
%w{hello x world}.each do |word|
  unless word.length < 2 do
    queue << word
    puts "Added to queue" 
  end
end
puts queue.inspect

I think this method makes it easier to modify the discrete elements of the queue operations. For example, I may want to comment out that call to “puts” someday, which would be tougher if I’d used the “and” operator to string it all together on one line. I might also want to add a debug log statement. Again, it gets tough when you’re trying to fit it all onto one line.

My opinion is that finding tricks in the language that allow you to string a bunch of steps onto one line aren’t always the best way to make good code. Sometimes, finding a way to make a set of statements look like a logical unit is a better choice.

May 26

I’m considering moving my comment system to disqus. I really like how their service helps keep online conversations easy to follow across multiple sites while making it easy not to lose track of the blog where the conversation began. It also lets users see more about a random commenter they come across on a blog.

Anyone else done this move on a Typo system?