WEB Advent 2008 / Use Responsibly

Hopefully you’re following Chris Cornutt’s advice, and you’re engaging the PHP community through a variety of media—forums, IRC, mailing lists, user groups, etc. If so, you’ve likely encountered the advice “Don’t reinvent the wheel,” or admonishments not to get sucked into the “NIH” (Not Invented Here) syndrome. If you follow it, you’re likely using somebody else’s code so that you can Get Things DonePEAR, or eZ Components, or one of the many frameworks (CakePHP, Symfony, or Zend Framework).

But what happens when you hit a snag? Say, for instance, the code isn’t doing what you think it should; then what do you do?

First, What Not to Do

  • Send long epistles to mailing lists, detailing all the poor design decisions in the project. Until you’ve established your credibility with the project’s community—sending in patches (more on that later), answering user questions, filing coherent bug reports (more on that, too)—I can guarantee you that such emails will fall on deaf ears, and likely get you filtered to /dev/null. No project is perfect, and many grow organically. The developers and contributors know this, and such emails are a slap in the face to all the effort they have poured into the project.
  • Threaten to “take your business elsewhere.” Sure, this may work with for-profit, shrinkwrapped, licensed software, but on a free, open source project? You’ll likely get the response, “Don’t forget to close the door behind you.”
  • Post vague reports such as “it doesn’t work” or “I tried this, but all I got were errors.” These are less than useful, and waste the time of others who now have to pry essential information from you to understand what exactly isn’t working, or what errors are being reported—often to find the code was incorrect to begin with.

What You Should Do

First, try and isolate the code. Comment out lines until you can reproduce the issue reliably with as few lines of code as possible. This may take some perseverence on your part. Often times, with MVC frameworks, you will actually need to do something scary and read the actual framework code, stepping through it to determine what’s going on under the hood.

For example, with Zend Framework, you may be getting an exception indicating that a particular controller was not found. What does this mean, exactly? Start with your entry point: a URL. Where does the URL get mapped to a controller? If you don’t know, go and ask in a real-time support channel, such as IRC. Okay, so the request object stores the URL; check to see that it has it. Where does it go next? Look in the code. It goes to the plugin broker. What plugins are loaded? None. Okay, next stop is the router. Well, I’m not adding any routes, so, looking at the code, it must hit the default route. Let’s see what it does. Huh, look at that, there’s the controller name. Now, next stop, another plugin. None. Then another, still none. Now we hit the dispatcher, and now it’s taking that controller and mapping it to a class name, and looking for a file. Oh, that file doesn’t exist! I didn’t create it!

So, while you’ve now spent a fair bit of your time tracking down what looked like a bug, but turned out to be your error, you’ve done two things:

  • Saved other people’s time. Remember, while some people may get paid to post to the list, you can’t assume that, particularly on open source projects. Never waste somebody else’s time.
  • Learned a fair bit about how the code works.

Eventually, however, you likely will encounter a real bug, and this is when your persistence will pay off. You’ll get to a point where you know that with certain input, you don’t get output you expect, and you can isolate it to a small bit of code. This is exactly what you should post:

  • The minimum amount of code to reproduce the issue,
  • What you were expecting to happen, and
  • What actually happened.

At this point, you have become a responsible open source user. You have performed due diligence and are now helping the project in a positive manner.

Solving the Problem

Chances are, if you’ve come this far, you may actually know how to solve the problem as well. So, it’s time to do so. But, again, you need to Do the Right Thing.

First, make sure you keep the original around. You’ll compare your changes to it using a tool called diff to create a patch file.

Second, you need to prove that what you have done fixes the issue. The common way to do that is to write a test that fails prior to the fix, and which passes after the fix is in place—in short, a unit test. The project you are using may have its own test suite, and the appropriate thing to do in such a situation is to add a test to that suite. Again, keep a copy of the original tests so you can provide a patch file. When you write it, use the reproduce code that you created as your test, and then assert against it. (See, that code does come in useful, after all!) I can’t cover testing fully here, for obvious reasons. Go bug Sebastian Bergmann if you want to learn about unit testing frameworks.

Finally, generate a patch file using diff. I won’t go into how to do so here. There are plenty of resources available, and many, many people you can ask online. Once you’ve created the patch file, attach it to the issue report.

Just as with responsible bug reporting, you’ve now done two things:

  • Saved somebody time. Even with good reproduce code in the issue report, somebody has to go to the trouble of writing a test with that code, creating assertions, and verifying the report. At this point, you’ve automated this process, all they need to do is apply the patch and run the tests. Again, never undervalue the time of others.
  • Gained some karma in the project for yourself. Remember my admonishment about long epistles about the shortcomings of projects? Well, open source is a meritocracy; people will only give credence to those who have demonstrated proficiency. By submitting quality reports and patches, you’re showing that you’re not only willing to criticize the project, but that you’ll make the time and effort to fix it as well.

So, start using that third-party code wisely. Dig under the hood, figure out how it works (or doesn’t) and contribute positively. Who knows? Maybe next year you will be writing this post!

Other posts