Documenting Your Code
I’ve been hearing a majority of developers saying things like “You’re code should be easy enough to understand that you don’t need to document it.” and “Comments are lies waiting to happen”. I was okay with this and after hearing this for a while I eventually stopped writing code comments.
I watched a conference talk recently on “Message Oriented Programming” where Brian basically came to a conclusion of a “protocol specification”. He was showing how when you define a protocol you are setting a standard of what goes in and what goes out. For a protocol it’s very important to specify types and usages. This got me thinking.
This past weekend I took part in an un-conference event called “Retro Ruby“. I spoke to a gentleman named Mark who was adamant about language quality and documentation. He said he wouldn’t even consider gems/libraries that weren’t documented. This also got me thinking.
From the band of people who claim that code should read as it’s own documentation, I’ve also heard that the test suite should be the documentation on how to use it. For my gem, that I’m most proud of, I’ve heavily tested it and refactored it quite a bit so it is “complete” in this sense.
Before I went to the un-conference this past weekend I went ahead and wrote inline YARD documentation for my gem PolyBelongsTo. I didn’t do it because I felt I had to; it was more like – I can’t think of anything new this needs so I might as well do something just for the heck of it. To my surprise adding documentation, and a badge for it, has increased the gem’s popularity. It is picking up star votes, slowly but surely, while the other gems remain stagnant.
All this leads me to believe that not documenting gems is more of a fad where pride is taken merely in the code clarity itself. If one is not hard headed against documentation then it might be wise to consider others who are of the mind, and/or need, to have documentation available for something they’ll trust and use. Code doesn’t always reveal all the possible outcomes. The documentation should clarify what types will be returned, and what are expected as input. This shows intent and can be used for proof in debugging as the “protocol standard”. I say ‘protocol’ because it represents something that’s, in a figure of speech, “set in stone”. Changes to specification should come in stages with advanced documentation notices, depreciation warnings, and semantic versioning to avoid breaking changes in minor versions. This will establish the highest trust between you, the author of the gem, and the end users.
Why YARD docs? Because I like the minimalist approach whenever I have the opportunity. YARD docs, from what I’ve seen, take the least amount of learning to get done. And you can just specify input required and output expected if you’re feeling lazy. It’s simple to learn, do, and test.
Unlike Python where you write the inline documentation just inside methods and classes, in Ruby you write it preceding methods and classes. The basics come down to a commented line (or as many as you’d like) describing what the method/class/module/constant does or is responsible for. If you have parameters that can be passed then the next line is where you put the @param descriptor along with the internal variable name of that param and type. And the last line before the method/class/module/constant is the output expected with @return .
# Converts the object into textual markup given a specific format. # # @param the_param_name [Symbol] the format type, `:text` or `:html` # @return [String] the object converted into the expected format. def to_format(the_param_name = :html) # format the object end
And that’s pretty much it. You can run ‘gem install yard‘ to test the coverage of your project by simply typing the command yard in the project folder. It will generate a doc/ folder with all the documentation in it and show you how many of each type Modules/Classes/Constants/Methods is, or is not, documented. Next you will need to add this to your .gitignore file as you don’t need the generated content published online as the tools online and elsewhere will generate documentation themselves.
Now you may want to look up a few things like different types that can be returned such as an Array with Objects and/or nil.
# @return [Array<Object, nil>]
True or false.
# @return [true, false]
Or maybe something more complex. The general documentation is at github.com/lsegal/yard/wiki/GettingStarted But I highly recommend looking at the Tags documentation at rubydoc.info/gems/yard/file/docs/Tags.md
Once you’ve got your methods and such documented and uploaded you can get a badge rating for your documentation with inch-ci.org. And you can have your online documentation generated by submitting your github repo at rubydoc.info via the “Add Project” button at the top right hand side.
Some documentation is better than none; if for no other reason than to be thinking about others needs and having transparency. Also it’s a great way to raise awareness, popularity, and trust. You don’t have to learn a lot to do it, and you don’t have to write a lot if you don’t want to. There may be times when you should write a lot; any place where it will save people time and effort I suggest doing so. YARD doc style isn’t limited to the basics, I believe it supports the full RDoc syntax as well (and some extras). So style it out as much as you’d like. In a sense it is a public presentation representing your project.
One thing I have been pondering… since we’re not supposed to test private methods, what about documenting them? That I don’t have an answer on but it’s worth thinking over. I feel that Zach would; after watching his talk “A Documentation Talk by: Zach Holman“. I think I may be inclined to document them for any private methods that “co-workers” may end up using as well; to help prevent them from thinking it should be changed to fit what they think it should do. I’m open for discussion on it.
One great point from the “Message Oriented Programming” talk, I linked to earlier, is that language itself is as a protocol. Language has both standards and meanings. Without the protocol, or better stated “specification”, meaning would be diluted away and language would become unusable/nonsense. People get confused enough in spoken, or written, language if the context is misunderstood; and it’s the same for programming. So I urge you to be open in considering documenting your code.
-Daniel P. Clark