Open Source for Beginners


Programming in today’s world is a marvelous thing. The open source movement has flourished; code is shared easily around the world. Small bits of programs, like Ruby gems or npm packages, are quickly installed at no cost. The open source community has even produced entire operating systems!

But for all its wonder, newcomers are intimidated by open source projects. As an example see this HN post which is just one of many echoing the same reservations: the new programmer feels too inexperienced or too uneducated to make contributions to open source.

This is the entirely wrong mindset for open source, however. The beauty of the process is the aggregation of many different people’s labors. Contributors are found across all skill and experience levels. To show a would-be contributor how easy it can be, let’s look at a recent bug I patched on the node_redis Github repo.

Redis is a popular “NoSQL” key-value store that runs entirely in memory so our data access is fast. node_redis is a set of Javascript bindings for Redis so we can access the datastore in our Node.js programs. I was exploring Redis in a Node.js program I was working on when I tried the following code:

1 // timestamp of data event in seconds
2 var timestamp = getTimeStamp();
3 
4 // HMSET is a Redis command to store a hash data type
5 redis_client.hmset(timestamp, {red: getRed(), blue: getBlue()});

Running this code would give the following error: ERR wrong number of arguments for 'hmset' command, and digging into the source revealed the following:

 1 // RedisClient.prototype.hmset
 2 if (args.length === 2 && typeof args[0] === "string" && typeof args[1] === "object") {
 3     // User does: client.hmset(key, {key1: val1, key2: val2})
 4     tmp_args = [ args[0] ];
 5     tmp_keys = Object.keys(args[1]);
 6     for (i = 0, il = tmp_keys.length; i < il ; i++) {
 7         key = tmp_keys[i];
 8         tmp_args.push(key);
 9         tmp_args.push(args[1][key]);
10     }
11     args = tmp_args;
12 }

In particular, the typeof args[0] === "string" condition was not being met as args[0] = timestamp in this case was of type Number. This check prevented the args variable from being assigned properly, resulting in the error. It turns out that node_redis expects the key variable to be a string, so I decided to test for a Number type variable and convert it with num.toString() if the user submitted a Number key. This fix was effectively 3 lines of code on 1, 6 and 7.

 1 // RedisClient.prototype.hmset
 2 // https://github.com/mranney/node_redis/commit/a2695f3d171ac9f64893c87d6e562b6176e17b64
 3 
 4 if (args.length === 2 && (typeof args[0] === "string" || typeof args[0] === "number") && typeof args[1] === "object") {
 5     // User does: client.hmset(key, {key1: val1, key2: val2})
 6     // assuming key is a string, i.e. email address
 7 
 8     // if key is a number, i.e. timestamp, convert to string
 9     if (typeof args[0] === "number") {
10         args[0] = args[0].toString();
11     }
12 
13     tmp_args = [ args[0] ];
14     tmp_keys = Object.keys(args[1]);
15     for (i = 0, il = tmp_keys.length; i < il ; i++) {
16         key = tmp_keys[i];
17         tmp_args.push(key);
18         tmp_args.push(args[1][key]);
19     }
20     args = tmp_args;
21 }

This fix didn’t require deep knowledge of Javascript, only the toString() method that most beginner developers have probably run across. This goes to show that the barrier to contributing to open source doesn’t have to be insurmountable… you just have to start somewhere. My contribution was by no means big, but it was something.

Essentially, the newcomer just needs to start experimenting with open source programs. Eventually you will find a bug or missing feature and you will be motivated enough to go fix it yourself. And boom, you are now an open source contributor! If you don’t know where to start looking for open source code, try searching Github for “[language I like] [one of my hobbies]” (e.g. “ruby bitcoin”) and see what you can find. Or try here: Mozilla Developer Network. The important thing is to start, no matter how small!