Travis Swicegood has a post questioning the value of the docblock. I have a deep sympathy with this sentiment.
Even on projects with extensive generated documentation, I find that kind of documentation to be of extremely low value. The problem with inline API documentation is that there is no sense of priority. Developers are encouraged to document every element that can possibly be documented. Then, when the documentation is generated, there is no way to distinguish the important from noise.
Another problem is restating the obvious. When a property or method really is well named, there may not be much more to say in the docblock. But, the mechanics of docblocks invites the programmer to say it anyway. So, you end up with comments like “$widget the widget.”
Duplication is also a significant problem. If you inherit from a base class or you implement an interface, there is a tendency to copy and paste the doc block from the parent to the children. This is an obvious maintenance problem. In fact, this is one of the major problems with comments. If comments restate what the code does, its a form of code duplication. When the code is changed, it requires changes in the comments. In this sense, comments make code harder to maintain.
Lately, I’ve been trying to curb the attractive nuisance aspect of docblock comments by replacing docblocks with comments like
// Definition in parent
or
// docblock intentionally omitted.
It would be nice if there were standard abbreviations for things like these. The idea being to eliminate the attractive nuisance of the commentable element by placing a comment there that is not a docblock, and then commenting only the elements where you have something to say.
Well, if docblocks are so bad, what is the alternative? Well, I’ve tried a few, including using a wiki for API documentation. Here is the problem. If duplication between the comment and the code is created by inline documentation, that maintenance problem becomes significantly worse with distance. If the documentation is external to the code, that distance really harms the ability to keep the documentation in sync with the code. So, docblocks are bad, but everything else is worse.
Docblocks were popularized by Sun and Java (or maybe Donald Knuth). But when sun was documenting their Java APIs with docblocks, they had a professional documentation team to do the work. When teams that don’t have a dedicated documenter role use these tools, I think they fall short.
So what is the solution? I’d like to see better techniques and conventions for solving the problems of docblocks: avoiding duplication, avoiding restating the obvious, and avoiding the tendency to docblock everything thats docblockable. Maybe there are more successful documenters out there who are handling these API documentation anti-patterns better than I am. I’d sure like to hear how.
Concerning the issue of duplicate documentation: if you employ the see tags (@see followed by a classname) then you can have links to other points in the documentation. For instance phpdoc supports the @see tag, and has a fairly straightforward use case. I often use it like this:
class A
{
// has some documentation
function one();
}
class B extends A
{
// @see A::one()
function one();
}
Of course substitute // with /** as appropriate. This allows me to have my documentation in the interface and just reference that documentation in the child. I recognize this isn’t as convenient for someone reading the documentation inline, but at least it means the generated documentation is more useful, and solves the problem of managing multiple instances of one document.
At dealnews, we only docblock the top of the file and each function. I find that docblocking each constant or anywhere else can become messy. And I often do not docblock the __constructor() method of a class when it is not needed. We also are not docblocking to generate external API. Its just in code comments. We just wanted a standard template for all developers to use. This way, the needed information is there, even if it is too much information sometimes. When our team had been together for several years, we got a little lax on the docblock. However, having hired two new people recently, you realize what is obvious to you is not obvious to a new team member. They need a little help. And sometimes, you do if you have not read the code in years.
Jeff, thanks. I was beginning to think I was part of a two-man minority. Now I know it’s at least three!
Regarding the duplication, there are a bunch of little known tricks in phpDocumentor. Since I worked with the maintainer for a period, I picked up all kinds of neat tricks.
One is templating:
The other in
{@inheritdoc}I’ve focused on putting more stuff in the module/class/higher level documentation, and leaving the API documentation for just the API. After all, the most important thing documentation can do is explain the core design and purpose, not how to call the methods with no coherency.
For example, here’s a doc-book-like documentation of a project I’ve released. The top-level documentation is more like a tutorial and design doc than traditional API docs, and I hope they are actually useful.
Doc-book-style documentation can still be useful, but you have to deliberately make sure to have a flow to the docs beyond the default non-flow.
While naming things well is important, I still find I like docblocks for a couple of things:
Also, it’s good to remember that docblocks are not just for API documentation. Many IDEs will be able to use the docblock to provide information on parameter typehints, and, using the reflection API, that same information can be used to do autodiscovery on classes used for things such as web services, MVC controllers, etc.
That said, probably the best documentation you can do is as Travis suggests: write good tests. If you write tests that test and describe the purpose of an interface, i.e., the contract it’s following, it’s much easier for a developer to go in and see how the class should be used. Furthermore, some testing frameworks, e.g. PHPUnit, have the ability to create “Agile Documentation” from tests that use the test name to generate documentation; this can often be very useful to a developer as well.
As with all documentation, docblocks can be extremely helpful, or a hindrance to programmers trying to figure out the program. I find that docblocks are a great place to clear up any ambiguity that may be in the method name: I expect that the method name is fairly explanatory and not doFoo()
Detailing the format of parameters, as Matthew notes, is essential. Unlike method names, these are not always immediately obvious, and usually can be greatly helped if there are a few examples too.
In the end, however, I think PHP’s documentation is a “docblock” like standard to aspire to. After generating skeleton XML files from the source C code, manual writers then fill in lots more tasty tidbits about the PHP functions. Done correctly, its a godsend.
One of the best advantages of docblocks it that some IDE-s can understand them and offer you additional functionality based on data they get from docblocks. For instance:
/*** Do stuff
*
* @param FirstClass $object
* @return SecondClass
*/
function do_stuff($object) {
// do stuff
}
Zend Studio will know what $object is and what do_stuff() returns and provide you with code completion for $object var and returned value. Being a code completion junky I find this really helpful and because of that I document almost everything.
Another point-of-view regarding “docblocking your codeâ€
Jeff Moore has written a comment to this blog entry from Travis Swicegood in which he basically says that inline-documentation of PHP-code is useless, since code is self-explanatory, especially if you have unit-tests that go with your code.
I can partl…
Docblocks as meta data is one aspect I didn’t consider when I wrote this.
[...] These thoughts are not revolutionary, but I think they make an important note, especially today when code generation is so popular, PHP source code to C extension conversion pops up again, and claims that source code documentation is overrated are heard (here and here). [...]
A technique I use for generating API documentation is using the ‘@access’ tag. This allows me to put some comments as @access private – which doesn’t get included in some documentation (if you compile your documentation with specific switches).
I fully agree to the point, that doc blocs can be very annyoing while coding, but as said above meta data is one aspect, that is very important.
I think it’s better to concentrate on the “important” Doc Blocs – which are on class Level and Method level. Well named properties (and params) can be left with a minimum of documentation. I only write more detailed documentation, when i leave the standard path of doing things.
For example i’ve got a lot of DB ids in my classes – which are always Integer greater 0 and can’t be negative. That’s why i often only put the “@return” and the “@param $param” information into my documentation, because in phpDocumentor the “getId()” getter would return void as default.
/**
* @return int
*/
public function getId() { ..
/**
* @param int $id
*/
public functiion setId() { …
easy to read and doesn’t waste much time..
check this out…
this is mine…
I only write more detailed documentation, when i leave the standard path of doing things.