In our upcoming Workshop that introduces developers in the practicalities of engaging with an open source project, guest speaker, Mark Johnson, will provide a real world example from his recent experience of contributing to the Moodle project. Real examples are a powerful learning tool and just as I had decided that we need to find more, an interesting example appears in my inbox from Dave Humphrey. Dave leads the Mozilla development courses at Seneca College Centre for Development of Open Technology. This course allows lucky students to get to grips with a real, large and ‘hairy’ code-base and engage with an active community in the form of the popular open source ‘product’ Mozzila Firefox and its sibling Thunderbird.
In this case the students engage in order to learn how to work with open source code through the open development processes that are encapsulated by the Mozilla governance model. This exposes them to many of experiences and critical skills that employers are crying out for but that can be extremely hard to teach in a computer science course.
David actually describes one of his own experiences of open development in his blog post, and I leave you to read the entire post which is quite complete in itself. While he covers only the early stages of the entire process of adding a feature, Dave does mention the later process such as code review. Dave’s problem is how to get code that works in one context to also work with an older version of the Mac operating system OS X, as required by the current release of Thunderbird. The following snippet encapsulates the point I wish to highlight here.
Now I was convinced I needed to do this for real. But how to deal with the differences between OS X 10.4 and 10.5+?
I wasn’t sure, so I did what you do in open source: I a) looked at the other Mozilla source code for clues; b) asked some people who might know. Looking through the code I saw lots of compile-time checks, but nothing at runtime. I needed to know when the app started-up what version I was on, and therefore which API to use. Next I tried asking on irc, in the #macdev channel. It was almost midnight, but luckily three people were around, and they each had a different idea for me: 1) I could consider using nsToolkit::OnLeopardOrLater(); 2) I could try doing what was done for the wifi scanning code (e.g., try, fail, fall back); 3) try to add this version check to another bug that was doing similar things. I read through all the options, and went to bed unsure of the best solution.
The next day I decided to ask two more people. One of them was the person who would eventually review my code, so his opinion mattered to me. The other was a friend who works for Mozilla and knows a lot about dependencies between various parts of the code. I really wanted to use nsToolkit::OnLeopardOrLater(), but it isn’t exported (e.g., it’s an internal API, and the .h file is not accessible to my class). They both suggested I just copy the code into my file, and later, when we move to 10.5+ support, remove it.
I made the change, and now the code supports both 10.4 with the existing drawing code, and 10.5+ with the new drawing API. I’m quite pleased with it, and hope that it gets accepted by my reviewer. Regardless of what happens, I learned a lot through this process. I learned how to mix C++ and Objective-C code, version differences between OS X APIs, build system tricks, how we do dynamic version checks in other parts of the code, etc. I was also reminded how much faster you can work when you work in a community setting vs. on your own. Through blogs, public source code, and irc I was able to get this done with only a couple hours of learning and work. It was time well spent, both for Thunderbird and for me.
I will make one point. Dave also learned something of the kind of real world messiness and compromises that often have to be made when dealing with existing code and many complex requirements. Messiness such as complex build systems, a mixture of languages, incomplete support for platforms . In the relatively isolated academic world of the classroom you can often get by without having to consider such constraints and dubious architectural decisions such as ‘just copy the code into my file, and later, when we move to 10.5+ support, remove it’. The complexities of the real world can only be learnt by engaging with real developers on a real project. Open source projects provide an ideal place for students to learn important skills whilst contributing their energy.