Ghost Doc Says the Damndest Things
Editorial Note: I originally wrote this post for the SubMain blog. You can check out the original here, at their site. While you’re there, have a look at GhostDoc, which can help both with code comment maintenance and the generation of help documentation.
Some years ago, I was doing work for some client or another. Honestly, I have no recollections of specifics with the exception of a preference for exhaustive commenting. Every class, every method, every property, and every field.
Of course, I didn’t learn this at first. I didn’t even learn it in a reasonable time frame. Instead, I learned it close to handover time. And so things got a little desperate.
Enter GhostDoc, My Salvation
Now, depending on your perspective, you might scold me for not diligently commenting all along. I will offer the explanation that the code had no public component and no intended APIs or extensions. It also required no “why” types of explanations; this was simple stuff.
The client cited policy. “We comment everything, and we’re taking over this code, so we want you to do the same.” Okie dokie.
Now, I knew that in a world of code generation and T4 templates, someone must have invented a tool that would generate some sort of comments or another. At the time, a quick Google search brought me to a saving grace: the free tool GhostDoc.
While it did not allow me to carpet bomb my code with comments in a single click (and understandably so), it did allow me to do it for entire files at a time. Good enough. I paid my non-commenting penance by spending an hour or so commenting this way.
And do you know what? It generated pretty respectable comments. I recall feeling impressed because I expected empty template comments. Instead, GhostDoc figured out how to string some verbs and nouns together.
But It’s Not All Roses
Let me get specific about capabilities and limitations. Had I tired to generate documentation for my Chess TDD codebases’s “MovePiece” method, GhostDoc would have treated me to this comment.
/// Moves the piece.
/// <param name="origin">The origin.</param>
/// <param name="destination">The destination.</param>
public void MovePiece(BoardCoordinate origin, BoardCoordinate destination)
var pieceToMove = GetPiece(origin);
pieceToMove.HasMoved = true;
ReconcileEnPassant(origin, destination, pieceToMove);
See what I mean? I did a pretty good job with clear naming in this method, and GhostDoc rewarded me with a method header that stands on its own. MovePiece() moves the piece. Specifically, it moves the origin to the destination. Not too shabby!
But what about less intuitive naming structures? Well, sometimes, things can get weird.
Do you know there was a Visual Studio addon that generated comments from method names? I once inherited a project full of these. pic.twitter.com/fuFjZjz4LJ
— Dan Abramov (@dan_abramov) December 15, 2016
Yes, that’s right. The ubiquitous “main” method for a C# application “mains the args.”
Okay, that ought to furnish a chuckle. But now that you see the issue, you can probably start to imagine all manner of ways to flummox the poor tool. (As an aside, you can probably also understand why they want to force you to pay more attention to the generated comments than just saying “generate comments for the whole solution.”)
What do you think used to happen back then for a no-op method that you named “DoNothing?” You’d get “Does the Nothing.” Good work on conjugation, but still missing the intent. How about an event handler called “AfterInsert?” That’s right. “Afters the Insert.” And “TaskComplete?” “Tasks the completed.” Now, here’s a tougher one: “OnClose.” You probably weren’t expecting “Oncloses the instance.”
Of course, other idiomatic programming concerns also befuddled the tool in different ways.
- ToModel() –> “Toes the model.”
- ToTitleCase() –> “Toes the title case.”
- ToComment() -> “Automatics the comment”
- ForgetPassword() –> “Forgets password”
- SignOut() –> “Signs the out”
Historically, you could make GhostDoc generate some pretty hilarious comments. This means that if you simply generated the comments and paid no further attention, you might look pretty absurd to someone auditing commit history. Fortunately, my oversight of the generated comments saved me from that fate.
Laugh at the Tool?
So should you laugh at GhostDoc. Well, sure. These comments are funny, and everyone ought to have a sense of humor.
But on a deeper level, no, not really. Natural language processing presents a difficult problem. Imagine yourself writing code to process class, method, and variable names. At first, you might thing it easy. But then you’d hit things like “ToString()” and “TaskComplete().” As a human and programmer, you understand these nuances. But how do you make your code do the same?
Oh, sure, you can hard-code some overrides for unique situations. But that will quickly become cumbersome. As you can see, you have a hard problem on your hands.
What You Can Do
What should you do, then, as a user of GhostDoc? Well, first and foremost, don’t just mindlessly generate comments. At the bare minimum, do what I did. Mindlessly generate comments, but also look to make sure that they make sense, correcting any that don’t.
But, beyond that, use GhostDoc as a starting point for meaningful communication. Generate XML doc comments only when doing so to communicate with someone, either via code comments or IntelliSense/help documentation. And when you do that, understand that GhostDoc simply offers you an intelligent starting point. The tool does not purport to replace you as a programmer or a communicator of your intent. It just gets you started.
Improving the Situation
Of course, GhostDoc has improved over the years. For instance, if I write a ToString() method and generate, it no longer offers me a “toes the string.” Instead, it does this.
/// Returns a <see cref="System.String" /> that represents this instance.
/// <returns>A <see cref="System.String" /> that represents this instance.</returns>
public string ToString()
return "I'm a board.";
Now, GhostDoc actually does something pretty sophisticated. It figures out that ToString() has a special place in the language and adapts accordingly, explaining that place with a marked-up comment.
Similarly, if you try to reproduce some of the shenanigans I detailed above, you will receive less obtuse results. The people working on the GhostDoc codebase are constantly seeking to improve the quality of the generated comments, even if they only serve as a starting point. But they could always use some help, so here is what I propose.
Write in or comment with funny or weird things that you can get GhostDoc to produce when you generate documentation. Seriously. It’ll give you, me, the readership, and the tool authors a good laugh. But it will also bring deficiencies to their attention, allowing them to address, correct, and improve. So go ahead. What are your favorite GhostDoc bloopers?