Sunday, December 30, 2007

Ruby which method

Just thought this was kinda interesting, the question came up in the merb IRC channel.


<wycats> you know what would be helpful... a which command in Ruby that went through the path and figured out what the path of some require would be


So, Here's a starting point:

def which(file)
path = $:.detect{|p| File.exist?("#{p}/#{file}.rb") }
"#{path}/#{file}.rb" if path
end


This of course doesn't account for .so files or .bundle, but could be pretty handy to include in an irbrc for debugging.

Friday, December 21, 2007

tests, specs and understanding code

Today, I was looking at a test. It read something like this:

def test_random_beans
beans = Beans.random(5)
assert_equal 5, beans.size
end


Simple, enough test right? Well, it was failing, beans.size returned 4. At first glance, I knew that a bean had been removed; so, probably it was safe to just change the assertion to

assert_equal 4, beans.size


This didn't really sit well with me though. Then later talking with a co-worker about the test. He was asking the question of why if we passed 5 to random it would only return 4 beans. Then later in the thread I asked for clarification:

so... Beans.random(5) should return 5 random beans?

That's when I realized, I had basically just written a spec for Beans.random. Had it been written that way from the beginning, it would have also made sense to have a spec to model the edge case of a user asking for more random beans then exist. This spec could read something like:

it "should return at most 4 beans from random" do
Beans.random(1000).should.return(4)
end


What I take away from this is the importance of specs go well beyond simple verification that the code is doing what you asked of it. It also, clearly documents in a human readable form what the code should be doing. This really improved the value of specs in my mind as more then just a pretty way of writing tests, but also a great way to document and understand the code.

Tuesday, December 04, 2007

Debugging Ruby net/http

I just discovered this really useful feature built into Ruby's network library.

set_debug_output

You can use this to get extensive debugging for everything sent or received.

You might use it like this:
@uri = URI.parse(service_url)
@url = Net::HTTP.new(@uri.host, @uri.port)
@url.set_debug_output $stderr


That will print out everything sent and received using that @url object.

Reading list