If programmers wanted to be technical writers, they probably would be technical writers and not programmers. You can see that tautology played out in many a Drupal module where the documentation (most likely a README.txt) is on the light side, and the code is on the heavy side. Don't get me wrong, there's some great documentation out there, and many valiant efforts on the part of developers, but you just can't always depend on extensive documentation - especially when you're looking at a module that's not particularly mature.
The truth of the matter, though, is you ought to know your way around PHP somewhat if you want to work with Drupal in any meaningful way; however you don't have to be a heavy weight programmer to figure things out. (And the cool thing is the more time you spend at it, the more you'll find yourself growing into the role.)
I recently had a project that involved writing a module to integrate a number of Drupal modules into a seamless workflow. The trouble with this project was that I hadn't worked with a number of them modules before, and the timeline was short. The modules in question, also, were only partially ported to Drupal 6 and though the modules were usable, the documentation wasn't yet updated.
The code is the documentation.
There are a number of strategies for grokking Drupal code when the documentation doesn't exist or isn't sufficient:
- Check out the hook_menu() implementation. This is usually the bones of a Drupal module. It maps a module's pages to functions (or callbacks in Drupal parlance), and will give you a sense of how the module is laid out, interface-wise. Use it to find the addresses for the module's pages and check them in the UI. I've often found pages I'd overlooked, hidden in an unexpected menu branch (like under Reports in the Admin menu). Once you've seen the page and what it does, check the callback that's called for that page in hook_menu().
- When checking menu callbacks, remember:
At their best functions should be like black boxes to the rest of the code. What really matters is what goes in and what comes out. What happens inside might appear complicated, but first off, concern yourself with recognizing what goes in and what comes out - ie. what parameters does it take, and what output does it return. Once you have that, then check and see if any database work is happening inside the function. Tables being read? Written to? Rows being deleted? What other functions are called - specifically functions defined by this same module? They'll most commonly bear the name of the module as part of their signature: mymodule_get_stuff(). Don't get too carried away by this, though. Remember, focus on the ins and outs.
- Learn to recognize known structures:
Drupal hooks like hook_form_alter(), hook_nodeapi(), Form API hooks and code, and theme hooks. When you recognize these structures, you know what's happening in that function to a large degree.
- Find out where the easily knowable helper functions in the module are employed. Use the find feature in your code editor.
- Look for any hooks the module defines using module_invoke_all('hookname'). These are points in a module's execution that the developer has decided are helpful to expose to others so that they might alter the module's function or springboard off from.
- Don't overlook a module's issue queue on Drupal.org, or its CVS commit messages. Check the module's project page to access these.