Reduce, Reuse, Recycle
We had an interesting and lively discussion in class the other day, and one point stayed with me after it was over. I asked the students about their experiences reading other people's code, or reusing code. Almost all of the students confessed that they hadn't done this before (that's one of the main things we fix in this class, so I wasn't surprised at this), but one student made a point I've never heard before. He said that he felt wrong about taking some code that another person has spent so much time on and using it so easily; that to do so was, in some unspoken by still real way, a kind of line-crossing that he wasn't willing to make. I think he was expressing respect, and the fact that he values the time and effort it takes to write something worth copying at all.
On Friday I was working on DXR, and I realized that I take these ideas for granted so much that it becomes easy to not talk about the "obvious." What was I doing exactly? I needed to take an IDL file (an Interface Description Language file, which is a language neutral way to represent a class) and get information about a) where each part of the IDL was defined (i.e., filename and line number); and b) get the signature for the type, inheritance info, methods, and attributes in a specific format (i.e., the same format as Dehydra). The specifics aren't important here, other than to say that I needed to take something like this and turn it into this. Even more, I had to do it many, many times in an automated way so that I could get proper index information for all IDL files in the Mozilla source code (there are lots of them!). This also means I needed a solution that works for the entire Mozilla tree and not just a few files.
So what do I do? I could teach myself the IDL syntax, write a parser, test it, and eventually I'd have what I need. But I don't have the patience for this. Actually, I never even considered this solution because there is another better way: reuse the code for Mozilla's xpidl IDL compiler! Earlier in the summer I mentioned the idea to a few friends, one of whom quickly whipped off a first draft. It was really close to what I wanted, and got me started.
But I needed it to do a bit more, and the answer to the question of "how" to make those changes was to study and reuse the code in xpidl_header.c. This is the code that actually takes the .idl file and produces the proper .h file, and it handles all the cases I care about. In order to make my code do what I needed, I carefully took a scalpel and slowly cut out the bits of code I didn't need, then grafted in some new ones I did, always looking at the code around for clues about the right way to proceed.
When I finished I had what I needed. It took me an hour or so by the time I properly tested it and confimed my output on a few edge cases I know about. Now compare that to what it would have taken if I'd tried to write this from scratch!
"That's great for you, but what about the poor sap who wrote the code you just took?" Well, I've been on both sides of this. A lot of people around the world use open source code I wrote once upon a time. I get mail almost every day from someone using it, asking a question about how to extend it, etc. And sometimes I get people sending me fixes. For example, one guy in South Africa used it in a teaching aid for students with poor eye sight. He told me about how he'd used the code in a way different from what I'd intended, and how in doing so he found and then fixed a nasty bug. It was a bug I'd known about too, but couldn't reproduce. However, his new use for my old code meant that it got exercised in a new way, and that was good not only for him, but for me and everyone using subsequent versions.
It's important in a course about open source for me to emphasize that in all of the cases I've listed above, the reuse represented a "fair use" of the original author's source code. It's not stealing to take code that someone has released under an open source license and study it, use it for new purposes, or even redistribute it. You just have to be clear what that license says and what you can actually do.
You show a lot of respect for an open source developer when you reuse his/her code, especially when you take the time to contribute back something you've improved, or report bugs you find. To do so is to become part of a community rather than remain a consumer, and I look forward to showing you much more about what these communities can do when they operate this way.