Posts

Ruby Substrings and Testing Legacy Code

Recently Josh Cronemeyer and I were working on writing a game in Ruby. Gosu , a 2D game library for Ruby and C++, and Chipmunk , a 2D Physics engine, do lots of the heavy lifting so we thought it would be a fun Saturday afternoon thing to do. However, the examples had no tests so when we tried to change some stuff, and of course it didn't work, we were all sorts of clueless as to why. Well, wrapping tests around legacy code is not a lot of fun but it is an effective way of debugging. Here's how I like to do it: Step one: Identify potentially troublesome code (As in "What the hell is that doing?"). Step two: Write some tests that verify the functionality of the code. Step three: Pull out the offending code into a method or methods. There's a fair bit of interplay between steps two and three, testing one piece may require extracting it. Step four: Either you've found your problem or you've accomplished four things: 1. You really understand the troublesom...

On Inject, Complexity, and George Carlin

Inject has been stalking me for over 2 years. The year was 2005 and I had decided that I would write a website in this new fangled Rails thing. But while debugging some plugin code I ran into inject. To my java encrusted eyes, it looked like this: weird_thing = dont_know.inject({}) {|m, o| m[o] = some_crazy_method o; m} Holy crap. I had no freakin' clue. I looked up the docs on inject and saw that inject, from what I could understand, was used to add up numbers in an array. Which confused me even more. Of course since then I've come to understand inject, but have remained wary as it can be awful confusing to those new to Ruby. Just recently I wrote about how some teammates and I decided against using it to shorten a method, because the particular use sacrificed readability. Then Brian Dainton wrote about how he loves inject. And finally, my team got in a rather spirited discussion over its use. One side of the argument was that it should be used with care as it...

A Small Rails Site and Why You Should Build One

Image
The other day I was showing Rails off to a friend of mine who wanted to know what all the fuss was about and I realized a shocking thing: I was horrible at starting a Rails site. Why? Because for the last year or so I've been working on large, established Rails codebases. Which is kinda cool as it shows how far Rails has come, but it sucks because one of the very cool things about Rails is how much you can do in a short amount of time. So I resolved to create and deploy a small site as a way to exercise some atrophied muscles and have some good old fun with Ruby and Rails. My father, Leslie Scruggs, is a sculptor and I had written him a pure html site back in 1999. And he maintained it editing the raw html files, creating his own thumbnails, and uploading via ftp. Not the easiest of tasks for a man in his 60's. So I created lesliescruggs.com which has an admin section so he can upload pics and get them resized and thumbnailed with 10% of the effort. Of course I us...

ActiveSupport::CoreExtensions::String::Inflections underscore

>> "ActiveSupport::CoreExtensions::String::Inflections".underscore => "active_support/core_extensions/string/inflections" >> "ActiveSupport::CoreExtensions::String::Inflections".underscore.camelize => "ActiveSupport::CoreExtensions::String::Inflections" Looks like Rails extension to the string class does more than underscore a string. Which is useful, but shouldn't the name be "relative_path" or something similar? When I see the method name "underscore" I know exactly what it means, except that's not what it does. The opposite of "underscore" is "camelize " which, again, may not have the best name. And if you want to find the declared constant specified in a string: >> "ActiveSupport::CoreExtensions::String::Inflections".constantize => ActiveSupport::CoreExtensions::String::Inflections Useful and an excellent name.

Return to Generating a Unique Number

In a previous post I discussed generating a unique id number for an order in our database. Read the original post for the full story, but to sum up, I decided that playing around with rand(100_000_000) was good enough. Martin Ankerl posted a comment pointing out that I was vulnerable to the Birthday Problem . So after a quick trip to wikipedia, I found out that if you have 23 people in a room you might think you have a 23/365 chance of having 2 people with the same birthdays, but no, your chances are closer to 50%! This is because in a group of 23 people there are 253 pairs each of which have a 1/365ish chance to have the same birthday. The formula to calculate how many are needed to give you a 50% chance of having a birthday collision is: .5 + sqrt(.25 + 2 * 365 * ln(2) ) = 22.9999 Which means the 50% chance of collision mark for 100,000,000 is: .5 + sqrt(.25 + 2 * 100,000,000 * ln(2) ) = 11774.600235771 Holy crap! I'm screwed if I can only have 12,000 orders before I get a...

When You Should Ignore Metrics

Our team has been doing a bang up job of reducing our complexity through our hit list (All of our methods are ranked by Flog score and we spend some part of every iteration picking the worst methods and trying to refactor them.). But sometimes we run into a situation where we prefer a high Flog score to a low one. For instance, this bit 'o code: def is_something?(x, y) x.foo == y.foo && x.bar == y.bar && x.blah == y.blah && # and 10 more lines of the same end which had a Flog score in the 60s. We could have changed it to this: def is_something?(x, y) ["foo", "bar", "blah", # and so on ].inject(true) do | a, b | a && x.send(b) == y.send(b) end end Which gave a us a much lower score. However that first method is crazy simple. Merely glance at it and you know what it's doing. The 'less complex' method? Even an experienced ruby dev would need a moment or two. As for a new dev... I can remem...

Automated Javascript Rails Testing

On my last project we did some javascript unit testing in browser using the unittest.js library from scriptaculous, but because it's kind of a pain to set up and integrate into your build, I didn't get it working on my current job. Which makes me a bad person. However, Dr Nic Williams has made yours and my life easier with his javascript_test plugin for rails. Now I can type: ruby script/generate javascript_test fancy_javascript_file And get a fancy_javascript_file_test.html to test my fancy_javascript_file.js. It's all set up to go right at the javascript file. Just open the html file in a browser and it runs the tests. The sweet doctor explains it all better than me so go check out his site. What I want to talk about is trying to integrate this into your Cruise Control build. The first problem we faced is that the tasks that come with the plugin don't close the tabs created in the browser. So after 10-20 builds, you're going to have way too many tabs an...