Psychedelic Panorama of Foo

Á¦ À̸§ÀÌ Inigo Montoya ÀÔ´Ï´Ù. ´ç½ÅÀÌ ³» ¾Æ¹öÁö¸¦ Á׿´¾î. Á×À» ÁغñÇØ.

ÀÏ¿äÀÏ, 3¿ù 16, 2008

 

When to Use One-Line Comments

¾Æ³çÇϼ¼¿ä. In my post on Comments in OO Java Software, I stated firmly that I believe one-line comments are bad smells and should be refactored. I still stand by that, but there are exceptions. This post is about those exceptional use cases.

Literate Programming

This is my #1 favorite excuse. What is it? Here's an explanation from the Literate Programming FAQ

Literate programming is a phrase coined by Donald Knuth to describe the approach
of developing computer programs from the perspective of a report or prose. The focus, then, 
is on description (and documentation) of the approach in human-readable form. This is in 
contrast to the normal approach of focusing on the code. -- David B. Thompson

Here are a few words about it from Dr. Knuth himself.

The structure of a software program may be thought of as a web that is made up of many
interconnected pieces. To document such a program we want to explain each individual part
of the web and how it relates to its neighbours. The typographic tools provided by TeX give
us an opportunity to explain the local structure of each part by making that structure visible,
and the programming tools provided by languages such as C or Fortran make it possible for
us to specify the algorithms formally and unambigously. By combining the two, we can
develop a style of programming that maximizes our ability to perceive the structure of a
complex piece of software, and at the same time the documented programs can be
mechanically translated into a working software system that matches the 
documentation. -- Donald E. Knuth 

In my own words, I would say that Literate Programming is a style of programming that makes source code a work of literature.

What advantage is there to writing software this way?

  • Reuse. Just like source code reuse is so popular in programming, documentation reuse is also a good idea. Literate Programming promotes documentation reuse by normalizing documentation that can be reused from source code to different documents.
  • Cross-referencing documentation. Documentation that is easy to read, navigate, and understand.
  • Documentation that can be treated as source code because it is in the source code.
    • Documentation version control. The documentation maintains the same version as the source.
    • Documentation and source code can always be found. If you have the source, you also have the documentation.
    • Documentation does not need to exist in a proprietary or specific format. It can be generated as long as it exists in the code.

Let's examine javadoc for example. This is a prime example of Literate Programming in OO software. It is useful because it can be generated from the source. A number of IDE's support it almost automatically. For example, Eclipse can be configured to produce javadoc comments for every method. These comments include input parameters, output values, exceptions, and cross-referencing with similar/related functionality. The javadoc comments are parsed and documentation is produced. The primary medium for output is HTML, but javadoc is not the tool. Javadoc is the style of documentation comments. The tool is irrelevant. For example, a tool could be created to produce LaTeX or even PDF output. That would not change that it is javadoc.

Javadoc is Literate Programming because it is a living work of literature within the source code. This does not mean it turns your program into a Literate Programming environment. The context is scoped just toward javadoc. It makes your source MORE Literate, but not a Literate Programming environment. It basically does for Java what WEB/CWEB did for Pasca, C, and other programming languages.

What does this have to do with one-line code comments? Let's examine javadoc again. If you follow the documentation commenting guidelines in The Elements of Java Style, then you have produced good documentation comments with input/output parameters, exception explanations, code examples, gotchas, domain-specific details, implementation details, et al.

However, the examples in the documentation comments are not continuously updated. They can change, and maybe even become neglected. Also, the source code itself is not included in any of the generated documentation. Therefore, we have all the documentation we may need, but no source to relate it to.

Another case would be where we have external documentation that refers to the source code. That being the document is not part of the source code like javadoc is, but rather it is created outside. Not only is it created outside the source code, but it refers to specific case internal to the source code. Let's analyze the requirements:

  • Has access to the source code.
  • Is generated.
  • Refers to specific cases in the source code, but not by line number.
  • Not effected by concurrent changes to code. Whenever the code changes, the documentation does not need to be updated, just regenerated.

Basically, pulling out specific sections of code to be inserted into the documentation when it is generated, and always grabbing the correct source. How is this done? There are a number of ways to do it, but one of the most popular ways is to tag the source code itself. Here's an example using a tool called the Snippet Plugin for referring to source code from Confluence.

// START SNIPPET: deleteAbstract public ActionForward deleteAbstract(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { return confirm(buildDeleteAbstractConfirmationQuestion(mapping, form, request, response), CONFIRM_DELETE_ABSTRACT_KEY, EMPTY_STRING); } // END SNIPPET: deleteAbstract

Notice the one-line comments that say ":START SNIPPET" and "END SNIPPET". These comments are used to tag where to start the snip and where to end it. This is a common pattern for extracting source example. A similar approach is used by The Pragmatic Programmers publishing house. The Pragmatic Programmers use a proprietary docbook stylesheet library to create consistent layouts for their books, but they also use a perl-based token replacement system that scans source code for tags written in one-line comments and replaces the appropriate docbook code in their build system. The end result is a system where source code only needs to be changed in one place and the documentation is updated with it. Reusable documentation.

Some people think the comments for the Snippet Plugin couple us to the Snippet Plugin or even to Confluence. That is just not true. The comment is configurable for the Snippet Plugin. That means that you can make it look however you want. It doesn't even need the word SNIPPET in it. I use listings with my TeX documentation to build with source code. It is the same concept. Using ambiguous tags that could look like anything really to tag sections of code for use in external documentation. Contrary to what people might think the source code would not require the Snippet Plugin or Confluence to run. That's the beauty of using a one-line comment.

This isn't a new concept. This kind of thing has been around for a long time. Donald E. Knuth came up with Literate Programming and the WEB system in 1988. The Pragmatic Programmers are just building on a solid foundation of concepts created by one of the greatest computer scientists in our history.

So that's one good reason to use one-line comments.

Temporary Metadata

What is that? Well, I think it is information that is abstract. It's not necessarily about the domain, the code or anything, but it is useful about a specific task. For example, javadoc and Eclipse both have this concept of a "todo." This is a temporary metadata comment. It exists for only a short while. It should only exist for a few hours at most. Some people manage to let them creep into the code and stay there indefinitely.

Below is another good example. For whatever reason (debugging, troubleshooting, whatever...) sometimes code is commented out. You don't want to use a C-Style comment or a documentation comment for this kind of stuff. It's best to use a one-line comment.

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { KualiConfigurationService configService = getService(KualiConfigurationService.class); ((ProposalDevelopmentForm)form).getProposalDevelopmentParameters().put("proposalNarrativeTypeGroup", configService.getParameter(Constants.PARAMETER_MODULE_PROPOSAL_DEVELOPMENT, Constants.PARAMETER_COMPONENT_DOCUMENT, "proposalNarrativeTypeGroup")); // ProposalDevelopmentForm proposalDevelopmentForm = (ProposalDevelopmentForm) form; // ProposalDevelopmentDocument proposalDevelopmentDocument = proposalDevelopmentForm.getProposalDevelopmentDocument(); // proposalDevelopmentDocument.populateNarrativeRightsForLoggedinUser(); ActionForward actionForward = super.execute(mapping, form, request, response); return actionForward; }

Keep in mind you do not want to check this into your source code versioning system. This is something you as a developer are the only one who will see. It should also only exist for a short period of time for your own sake. Again, for the sake of the planet, don't check this stuff into CVS/SVN. Visual Sourcesafe is ok.

ű×: , ,





This page is powered by Blogger. Isn't yours?

¿¡ °¡ÀÔ °Ô½Ã¹° [Atom]