SubMain - CodeIt.Right The First Time!


Support Community for SubMain Products
 Home Products Services Download Purchase Support
in Search
Home Forums Blogs Tutorials/CIR Tutorials/GD Downloads
Welcome to SubMain Community Sign in | Join | Help

SubMain Blog

Browse by Tags

All Tags » GhostDoc   (RSS)

  • How C# Spell Check Helps Your Team and Your Code

    If you didn’t know that C# spell check was a thing, it is.  For one thing, you can run a normal spelling analysis on any comments in your code.  That shouldn’t surprise.  But you can also check the code itself for spelling errors. That may seem like a strange thing at first.  Wouldn’t a C#...

    The post How C# Spell Check Helps Your Team and Your Code appeared first on Software Quality Blog - SubMain Software.

  • GhostDoc Pro Beta brings true Visual Editing to XML Comments

    The latest Beta of GhostDoc introduces a new feature that makes XML documentation authoring a breeze – Visual Edition for XML Comments. The number one challenge authoring XML Comments that we heard from our users has been keeping the valid XML which includes encoding HTML formatting tags, code samples, etc. Many of these don’t even...
  • Released: GhostDoc v5.5

    GhostDoc version 5.5 delivers compatibility with VS2017 RTM as well as a number of fixes:

    • VS2017 RTM support
    • GhostDoc is now also available as VSIX for VS2017
    • Documentation Hints no longer visible in the Debug mode
    • Fixed issue wrapping lines within the <value></value> tag
    • In the Offline Activation Preview - the fields are now auto-selected on focus/click for easy copying
    • GhostDoc is no longer adding extra line when re-documenting header in VB
    • GhostDoc is no longer appending generated XML comments to the existing comment when using auto-generated properties in VB

    For the complete list of changes, please see What's New in GhostDoc v5

    For overview of the v5.0 features, visit Overview of GhostDoc v5.0 Features

    Download the new build at

  • Add Custom Content to Your Help Documentation

    For the last several years, I've made more and more of my living via entrepreneurial pursuits.  I started my career as a software developer and then worked my way along that career path before leaving fulltime employment to do my own thing.  These days, I consult, but I also make training content, write books, and offer productized services.

    When you start to sell things yourself, you come to appreciate the value of marketing.  As a techie, this feels a little weird to say, but here we are.  When you have something of value to offer, marketing helps you make interested parties aware of your offer.  I think you'd like this and find it worth your money, if you gave it a shot.

    In pursuit of marketing, you can use all manner of techniques.  But today, I'll focus on a subtle one that involves generating a good reputation with those who do buy your products.  I want to talk about making good documentation.

    The Marketing Importance of Documentation

    This probably seems an odd choice for a marketing discussion.  After all, most of us think of marketing as what we do before a purchase to convince customers to make that purchase.  But repeat business from customer loyalty counts for a lot.  Your loyal customers provide recurring revenue and, if they love their experience, they may evangelize for your brand.

    Providing really great documentation makes an incredible difference for your product.  I say this because it can mean the difference between frustration and quick, easy wins for your user base.  And, from a marketing perspective, which do you think makes them more likely to evangelize?  Put yourself in their shoes.  Would you recommend something hard to figure out?

    For a product with software developers as an end user, software documentation can really go a long way.  And with something like GhostDoc's "build help documentation" feature, you can notch this victory quite easily.  But the fact that you can generate that documentation isn't what I want to talk about today, specifically.

    Instead, I want to talk about going the extra mile by customizing it.

    Introducing "Conceptual Content"

    You can easily generate documentation for your API with the click of a button.  But you can also do a lot more.

    GhostDoc Enterprise features something called "Conceptual Content."  Basically, it allows you to customize and add on to what the engine generates using your code and XML doc comments.  This comes in handy in ways limited only by your imagination, but here are some ideas.

    • A welcome page.
    • A support page.
    • A "what's new" page.
    • Including a EULA/license.
    • Custom branding.

    You probably get the idea.  If you already look to provide documentation for your users, you no doubt have some good additional thoughts for what they might value.  Today, I'm going to show you the simplest way to get going with conceptual content so that you can execute on these ideas of yours.

    How It Works at a High Level

    For GhostDoc to work its documentation-generating magic, it creates a file in your solution directory named after your solution.  For instance, with my ChessTDD solution, it generates a file called "ChessTDD.sln.GhostDoc.xml."  If you crack open this file, you will see settings mirroring the ones you select in Visual Studio when using GhostDoc's "Build Help Documentation."

    To get this going, we face the task of basically telling this file about custom content that we will create.  First, close out of Visual Studio, and let's get to work hacking at this thing a bit.  We're going to add a simple, text-based welcome page to the standard help documentation.  To do this, we need the following things.

    • Modifications to the GhostDoc XML file.
    • The addition of a "content" file describing our custom content,
    • Addition of a "content" folder containing the AML files that make up the actual, custom pages.

    Let's get started.

    The Nuts and Bolts

    First, open up the main GhostDoc XML file and look for the "ConceptualContent" section.  It looks like this.

    <ConceptualContent> <ContentLayout /> <MediaContent /> </ConceptualContent>

    In essence, this says, "no conceptual content here."  We need to change that.  So, replace the empty ContentLayout entry with this (substituting the name of your solution for "ChessTDD" if you want to follow along with your own instead of my ChessTDD code.)

    <ContentLayout file="ChessTDD.content" folder="Content\" />

    Next up, you need to create the file you just told it about, ChessTDD.content.  This file goes in the same directory as your solution and looks like this.

    <?xml version="1.0"
    encoding="utf-8"?> <Topics> <Topic id="4684cc2f-3179-4871-b7a4-ad69f0f260a3" visible="True" isDefault="true" title="Welcome"> <HelpKeywords> <HelpKeyword index="K" term="Welcome" /> </HelpKeywords> </Topic> </Topics>

    For the ID, I simply generated a GUI using this site.  This ID simply needs to be unique, and to match the next file that we'll create.  Next up, create the folder you told ContentLayout about called, "Content."  Then add the file Welcome.aml to that folder, with the following text.

    <?xml version="1.0"
    encoding="utf-8"?> <topic id="4684cc2f-3179-4871-b7a4-ad69f0f260a3" revisionNumber="1"> <developerConceptualDocument xmlns="" xmlns:xlink=""> <introduction> <para>Welcome
    to our help section!</para> </introduction> </developerConceptualDocument> </topic>

    Notice that we use the same GUID here as in the content file.  We do this in order to link the two.

    Let's Give it a Whirl

    With your marked up Ghost Doc XML file, the new content file, and the new Content folder and welcome AML file, you can now re-launch Visual Studio.  Open the solution and navigate through GhostDoc to generate the help documentation CHM file.


    There you have it.  Now you can quickly add a page to the automatically generated help documentation.

    Keep in mind that I did the absolute, dead simplest possible thing I could do for demonstration purposes.  You can do much more.  For example:

    • Adding images/media to the pages.
    • Have cross-links in there for reference.
    • Add snippets and examples.
    • Build lists and tables.

    As I said earlier, you'll no doubt think of all manner of things to please your user base with this documentation.  I suggest getting in there, making it your own, and leaving a nice, personal touch on things for them.  When it comes to providing a good user experience, a little can go a long way.

    Related resources

    Learn how GhostDoc can help to simplify your XML Comments, produce and maintain quality help documentation.

    About the Author

    Erik Dietrich

    I'm a passionate software developer and active blogger. Read about me at my site. View all posts by Erik Dietrich

  • GhostDoc Says the Damndest Things

    Editorial note: most of the GhostDoc bloopers below are a history, but they provide for a good laugh. We encourage you to share the GhostDoc goofs you have encountered – they are great for entertainment as well as give us a chance to improve the product.

    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 tried to generate documentation for my Chess TDD codebases's MovePiece method, GhostDoc would have treated me to this comment.

    /// <summary> /// Moves
    the piece. /// </summary> /// <param
    name="origin">The origin.</param> /// <param
    name="destination">The destination.</param> public void MovePiece(BoardCoordinate
    origin, BoardCoordinate destination) { VerifyCoordinatesOrThrow(origin, destination); var pieceToMove = GetPiece(origin);
    AddPiece(pieceToMove, destination); RemovePiece(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.

    — Dan Abramov (@dan_abramov) December 15, 2016

    Yes, that's right.  The ubiquitous "main" method for a C# application "mains the args."

    What Else?

    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"

    Or how about

    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.

    /// <summary> /// Returns
    a <see cref="System.String" /> that
    represents this instance. /// </summary> /// <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.

    Luckily, there is a Summary Override feature in GhostDoc, and you should use it to improve the future generated comments once you find a new blooper.

    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?

    Learn more about how GhostDoc can help simplify your XML Comments, produce and maintain quality help documentation.

    About the Author

    Erik Dietrich

    I'm a passionate software developer and active blogger. Read about me at my site. View all posts by Erik Dietrich

  • You Can Use GhostDoc's Document This with JavaScript

    If you haven't lived in a techie cave the last 10 years, you've probably noticed JavaScript's rise to prominence.  Actually, forget prominence.  JavaScript has risen to command consideration as today's lingua franca of modern software development.

    I find it sort of surreal to contemplate that, given my own backstory.  Years (okay, almost 2 decades) ago, I cut my teeth with C and C++.  From there, I branched out to Java, C#, Visual Basic, PHP, and some others I'm probably forgetting.  Generally speaking, I came of age during the heyday of object oriented programming.

    Oh, sure I had awareness of other paradigms.  In college, I had dabbled with (at the time) the esoteric concept of functional programming.  And I supplemented "real" programming work with scripts as needed to get stuff done.  But object-oriented languages gave us the real engine that drove serious work.

    JavaScript fell into the "scripting" category for me, when I first encountered it, probably around 2001 or 2002.  It and something called VBScript competed for the crown of "how to do weird stuff in the browser, half-baked hacky languages."  JavaScript one that battle and cemented itself in my mind as "the thing to do when you want an alert box in the browser."

    Even as it has risen to prominence and inspired a generation of developers, I suppose I've never really shed my original baggage with it.  While I conceptually understand its role as "assembly language of the web," I have a hard time not seeing the language that was written in 10 days and named to deliberately confuse people.

    GhostDoc, Help, and IntelliSence

    I lead with all of this to help you understand the lens through which to read this post.  As a product of the strongly typed, object-oriented wave of programmers, my subconscious still regards JavaScript as something of an afterthought, its dominance notwithstanding.  And so when I see advances in the JavaScript world, I tend to think, "Oh, cool, you can do that with JavaScript too!"

    I'll come back to that shortly.  But first, I'd like to remind you of a prominent GhostDoc feature.  Specifically, I'm referring to the "Document This" capability.  With your cursor inside of a method or type, you can use this capability to generate instant, well-formatted, XML doc comments.  Thoroughly documented code sits just a "Ctrl-Shift-D" away.

    If you work with C# a lot and generate public APIs and/or help documentation, you will love this capability.  It doesn't absolve you of needing to add specific contest.  But it does give you a thorough base upon which to build.  For example, consider this method from my ChessTDD example codebase.

    /// <summary> /// Gets
    the moves from. /// </summary> /// <param
    name="startingLocation">The starting location.</param> /// <param
    name="boardSize">Size of the board.</param> /// <returns>IEnumerable&lt;BoardCoordinate&gt;.</returns> public override IEnumerable<BoardCoordinate> GetMovesFrom(BoardCoordinate
    startingLocation, int boardSize = Board.DefaultBoardSize)
    { var oneSquareAwayMoves = GetAllRadialMovesFrom(startingLocation, 1); return oneSquareAwayMoves.Where(bc => bc.IsCoordinateValidForBoardSize(boardSize));

    I took that un-commented method and used GhostDoc to generate this.  Now, I Should probably update the summary, but I really don't see any other deficiencies here.  It nails the parameter names, and it even escapes the generic return type for readability.

    It Works with JavaScript, Too

    Now, as I've said earlier, I don't really play much in the JavaScript world.  I generally focus on application code and server side stuff, delving into the realm of the client side browser only when necessary to get things done.  So you can imagine my reaction to learn that GhostDoc can do this with JavaScript too.  It can produce sophisticated XML doc comments that allow for use in generating help and with IntelliSence.

    Actually, if I really want to embarrass myself, I'll confess that my initial reaction was, "JavaScript code has IntelliSence?"  I think maybe I knew that, but I assumed that such a thing would offer little value in a dynamically typed language.  Shows what I know.  But then, once I got over that initial wave of ignorance, I thought, "cool!" at the idea that you could generate documentation for JavaScript.  I then wondered if well-documented JavaScript was more or less rare than well documented C#.  That jury has yet to come back, as far as I know.

    Let's Take a Look

    Let's take a look at what GhostDoc actually does here.  To demonstrate, I created a branch of my ChessTDD project, to which I added an ASP MVC front end.  This plopped some JavaScript right in my lap, in the form of the default files in the "Scripts" folder.  To see this in action, I popped open modernizr-2.6.2.js and found a method upon which to experiment.


    ShivMethods sounded... interesting, in a prison yard sort of way.  As a publicly consumable library, it already has documentation.  And, as I learned by playing around, that documentation already gets picked up by IntelliSense.  But I figured I'd see what happened by using GhostDoc anyway, for comparison's sake.

    So I lazily put my cursor randomly inside the method and fired away with a Ctrl-Shift-D.  Check it out.


    As you can see, GhostDoc puts the comment inside of the method and behaves largely as it would with C#.  In case you're wondering about the stylistic difference, GhostDoc does this because it's the more Microsoft-preferred way.  To underscore that, look what happens now when we consume this method with IntelliSense.


    As you can see, IntelliSense gives preference to the comments generated by GhostDoc.

    The Takeaway

    What's my main point here?  I simply wanted to share that you can use GhostDoc for JavaScript just as you can with C# or VB.

    Forget about my crotchety ways and biases.  Your JavaScript/client-side code is every bit as important as what you write anywhere else.  You should treat it as such when documenting it, creating help for it, and making sure users know how to consume your libraries.  So make sure you've got Ctrl-Shift-D at the ready when using Visual Studio, regardless of where the code gets executed.

    Learn more about how GhostDoc can help simplify your XML Comments, produce and maintain quality help documentation.

    About the Author

    Erik Dietrich

    I'm a passionate software developer and active blogger. Read about me at my site. View all posts by Erik Dietrich

  • GhostDoc - Customizing Generated Method Header Comments

    Last month, I wrote a post introducing you to T4 templates.  Near the end, I included a mention of GhostDoc's use of T4 templates in automatically generating code comments.  Today, I'd like to expand on that.

    To recap very briefly, recall that Ghost Doc allows you to generate things like method header comments.  I recommend that, in most cases, you let it do its thing.  It does a good job.  But sometimes, you might have occasion to want to tweak the result.  And you can do that by making use of T4 Templates.

    Documenting Chess TDD

    To demonstrate, let's revisit my trusty toy code base, Chess TDD.  Because I put this code together for instructional purposes and not to release as a product, it has no method header comments for IntelliSense's benefit.  This makes it the perfect candidate for a demonstration.

    If I had released this as a library, I'd have started the documentation with the Board class.  Most of the client interaction would happen via Board, so let's document that.  It offers you a constructor and a bunch of semantics around placing and moving pieces.  Let's document the conceptually simple MovePiece method.

    public void MovePiece(BoardCoordinate
    origin, BoardCoordinate destination) { VerifyCoordinatesOrThrow(origin, destination); var pieceToMove = GetPiece(origin);
    AddPiece(pieceToMove, destination); RemovePiece(origin); pieceToMove.HasMoved = true;
    ReconcileEnPassant(origin, destination, pieceToMove); }

    To add documentation to this method, I simply right click it and, from the GhostDoc context menu, select "Document This."  Alternatively, I can use the keyboard shortcut Ctrl-Shift-D.  Either option yields the following result.

    /// <summary> /// Moves
    the piece. /// </summary> /// <param
    name="origin">The origin.</param> /// <param
    name="destination">The destination.</param> public void MovePiece(BoardCoordinate
    origin, BoardCoordinate destination) { VerifyCoordinatesOrThrow(origin, destination); var pieceToMove = GetPiece(origin);
    AddPiece(pieceToMove, destination); RemovePiece(origin); pieceToMove.HasMoved = true;
    ReconcileEnPassant(origin, destination, pieceToMove); }

    Let's Make a Tiny Tweak

    Alright, much better!  If I scrutinize the comment, I can imagine what an IntelliSense-using client will see.  My parameter naming makes this conceptually simple to understand, so the IntelliSense will tell the user that the first parameter represents the origin square and the second parameter the destination.

    But let's say that as I look at this, I find myself wanting to pick at a nit.  I don't care for the summary taking up three lines -- I want to condense it to one.  How might I do that?

    Well, let's crack open the T4 template for generating a method header.  Recall that you do this in Visual Studio by selecting Tools->Ghost Doc->Options, and picking "Rules" from the options pane.


    If you double click on "Method Template", as highlighted above, you will see an "Edit Rule" Window.  The first few lines of code in that window look like this.

    <#@ template language="C#" #> <# CodeElement
    codeElement = Context.CurrentCodeElement; #> ///
    <summary> ///<# GenerateSummaryText(); #> ///
    </summary> <# if(codeElement.HasTypeParameters)
    { for(int i = 0;
    i < codeElement.TypeParameters.Length;
    { TypeParameter typeParameter = codeElement.TypeParametersIdea; #>

    Hmmm.  I cannot count myself an expert in T4 templates, per se, but I think I have an idea.  Let's put that call to GenerateSummaryText() inline between the summary tags.  Like this:

    <#@ template language="C#" #> <# CodeElement
    codeElement = Context.CurrentCodeElement; #> ///
    <summary><# GenerateSummaryText(); #></summary>

    That should do it, right?  Let's regenerate the comment and see what it looks like.  This results in the following.

    /// <summary>Moves
    the piece. /// </summary> /// <param
    name="origin">The origin.</param> /// <param
    name="destination">The destination.</param> public void MovePiece(BoardCoordinate
    origin, BoardCoordinate destination) { VerifyCoordinatesOrThrow(origin, destination); var pieceToMove = GetPiece(origin);
    AddPiece(pieceToMove, destination); RemovePiece(origin); pieceToMove.HasMoved = true;
    ReconcileEnPassant(origin, destination, pieceToMove); }

    Uh, oh.  It made a difference, but somehow we only got halfway there.  Why might that be?

    Diving Deeper

    To understand, we need to look at the template in a bit more detail.  The template itself has everything on one line, and yet we see a newline in there somehow.  Could GenerateTextSummary cause this, somehow?  Let's scroll down to look at it.  Since this method has a lot of code, here are the first few lines only.

    private void GenerateSummaryText()
    { if(Context.HasExistingTagText("summary"))
    { this.WriteLine(Context.GetExistingTagText("summary"));
    } else if(IsAsyncMethod())
    { this.WriteLine(Context.ExecMacro("$(MethodName.Words.ExceptLast)") + " as
    an asynchronous operation.");
    } else if(IsMainMethod())
    { this.WriteLine("Defines
    the entry point of the application.");
    } }

    Aha!  Notice that we're calling WriteLine.  What if we did a find and replace to change all of those to just Write?  Let's try.  (To do more serious operations like this, you will want to copy the text out of the editor and into your favorite text editor in order to get more operations).

    Once you have replaced all instances of WriteLine with Write in the template, here is the new result.

    /// <summary>Moves
    the piece.</summary> /// <param
    name="origin">The origin.</param> /// <param
    name="destination">The destination.</param> public void MovePiece(BoardCoordinate
    origin, BoardCoordinate destination) { VerifyCoordinatesOrThrow(origin, destination); var pieceToMove = GetPiece(origin);
    AddPiece(pieceToMove, destination); RemovePiece(origin); pieceToMove.HasMoved = true;
    ReconcileEnPassant(origin, destination, pieceToMove); }



    As you play with this, you might have noticed a "Validate" button in the rule editor.  Use this liberally!  This button will trigger a parsing of the template and provide you with feedback as to validity.  The last thing you want to do is work in here for many iterations and wind up with no idea what you broke and when.

    When working with these templates, think of this as equivalent to compiling.  You wouldn't want to sit for 20 minutes writing code with no feedback as to whether it builds or not.  So don't do it with these templates.

    The Power at Your Disposal

    I'll wrap here for this particular lesson, but understand that we have barely scratched the surface of what you can do.  In this post, we just changed a bit of the formatting to suit a whim I had.  But you can really dive into ways of reasoning about and documenting the code if you so choose.

    Stay tuned for future posts on more advanced tips and tricks with your comment templates.

    Learn more about how GhostDoc can help simplify your XML Comments, produce and maintain quality help documentation.

    About the Author

    Erik Dietrich

    I'm a passionate software developer and active blogger. Read about me at my site. View all posts by Erik Dietrich

  • Intro to T4 Templates: Generating Text in a Hurry

    Today, I'd like to tackle a subject that inspires ambivalence in me.  Specifically, I mean the subject of automated text generation (including a common, specific flavor: code generation).

    If you haven't encountered this before, consider a common example.  When you file->new->(console) project, Visual Studio generates a Program.cs file.  This file contains standard includes, a program class, and a public static void method called "Main."  Conceptually, you just triggered text (and code) generation.

    Many schemes exist for doing this.  Really, you just need a templating scheme and some kind of processing engine to make it happen.  Think of ASP MVC, for instance.  You write markup sprinkled with interpreted variables (i.e. Razor), and your controller object processes that and spits out pure HTML to return as the response.  PHP and other server side scripting constructs operate this way and so do code/text generators.

    However, I'd like to narrow the focus to a specific case: T4 templates.  You can use this powerful construct to generate all manner of text.  But use discretion, because you can also use this powerful construct to make a huge mess.  I wrote a post about the potential perils some years back, but suffice it to say that you should take care not to automate and speed up copy and paste programming.  Make sure your case for use makes sense.

    The Very Basics

    With the obligatory disclaimer out of the way, let's get down to brass tacks.  I'll offer a lightning fast getting started primer.

    Open some kind of playpen project in Visual Studio, and add a new item.  You can find the item in question under the "General" heading as "Text Template."


    Give it a name.  For instance, I called mine "sample" while writing this post.  Once you do that, you will see it show up in the root directory of your project as  Here is the text that it contains.

    <#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".txt" #>

    Save this file.  When you do so, Visual Studio will prompt you with a message about potentially harming your computer, so something must be happening behind the scenes, right?  Indeed, something has happened.  You have generated the output of the T4 generation process.  And you can see it by expanding the caret next to your file as shown here.


    If you open the Sample.txt file, however, you will find it empty.  That's because we haven't done anything interesting yet.  Add a new line with the text "hello world" to the bottom of the file and then save.  (And feel free to get rid of that message about harming your computer by opting out, if you want).  You will now see a new Sample.txt file containing the words "hello world."

    Beyond the Trivial

    While you might find it satisfying to get going, what we've done so far could be accomplished with file copy.  Let's take advantage of T4 templating in earnest.  First up, observe what happens when you change the output extension.  Make it something like .blah and observe that saving results in Sample.blah.  As you can see, there's more going on than simple text duplication.  But let's do something more interesting.

    Update your file to contain the following text and then click save.

    <#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".txt" #> <# for(int i = 0;
    i < 10;
    World {i}"); #> 

    When you open Sample.txt, you will see the following.

    Hello World 0
    Hello World 1
    Hello World 2
    Hello World 3
    Hello World 4
    Hello World 5
    Hello World 6
    Hello World 7
    Hello World 8
    Hello World 9

    Pretty neat, huh?  You've used the <# #> tokens to surround first class C# that you can use to generate text.  I imagine you can see the potential here.

    Oh, and what happens when you type malformed C#?  Remove the semicolon and see for yourself.  Yes, Visual Studio offers you feedback about bad T4 template files.

    Use Cases

    I'll stop here with the T4 tutorial.  After all, I aimed only to provide an introduction.  And I think that part of any true introduction involves explaining where and how the subject might prove useful to readers.  So where do people reasonably use these things?

    Perhaps the most common usage scenario pertains to ORMs and the so-called impedance mismatch problem.  People create code generation schemes that examine databases and spit out source code that matches with them.  This approach spares the significant performance hit of some kind of runtime scheme for figuring this out, but without forcing tedious typing on dev teams.  Entity Framework makes use of T4 templates.

    I have seen other uses as well, however.  Perhaps your organization puts involved XML configuration files into any new projects and you want to generate these without copy and paste.  Or, perhaps you need to replace an expensive reflection/runtime scheme for performance reasons.  Maybe you have a good bit of layering boilerplate and object mapping to do.  Really, the sky is the limit here, but always bear in mind the caveat that I offered at the beginning of this post.  Take care not to let code/text generation be a crutch for cranking out anti-patterns more rapidly.

    The GhostDoc Use Case

    I will close by offering a tie-in with the GhostDoc offering as the final use case.  If you use GhostDoc to generate comments for methods and types in your codebase, you should know that you can customize the default generations using T4 templates.  (As an aside, I consider this a perfect use case for templating -- a software vendor offering a product to developers that assists them with writing code.)

    If you open GhostDoc's options pane and navigate to "Rules" you will see the following screen.  Double clicking any of the templates will give you the option to edit them, customizing as you see fit.


    You can thus do simple things, like adding some copyright boilerplate, for instance.  Or you could really dive into the weeds of the commenting engine to customize to your heart's content (be careful here, though).  You can exert a great deal of control.

    T4 templates offer you power and can make your life easier when used judiciously.  They're definitely a tool worth having in your tool belt.  And, if you make use of GhostDoc, this is doubly true.

    Learn more about how GhostDoc can help simplify your XML Comments, produce and maintain quality help documentation.

    About the Author

    Erik Dietrich

    I'm a passionate software developer and active blogger. Read about me at my site. View all posts by Erik Dietrich

  • Released: GhostDoc v5.4 update

    Version 5.4 of GhostDoc is a maintenance update for the v5.0 users:

    • VS2017 RC integration
    • New menu items - Getting Started Tutorial and Tutorials and Resources
    • (Pro) (Ent) Edit buttons in Options - Solution Ignore List and Options - Spelling Ignore List
    • (Pro) (Ent) Test button in Options - Solution Ignore List
    • (Ent) Now GhostDoc shows error message when Conceptual Content path is invalid in the solution configuration file
    • Fixed PathTooLongException exception when generating preview/build help file for C++ projects
    • (Ent) Updated, moved all conceptual content files inside the project in GhostDoc Enterprise\Samples\Conceptual Content\
    • Improved documenting ReadOnly auto-properties in VB
    • Resolved issue re-documenting a type at the top of source code file in VB
    • Resolved issue with generating preview of the <seealso> tag for generics in VB

    For the complete list of changes, please see What's New in GhostDoc v5

    For overview of the v5.0 features, visit Overview of GhostDoc v5.0 Features

    Download the new build at

  • Survey: What are your biggest code documentation challenges right now?

    We are looking for your input and we're willing to bribe you for answering one very simple question: What are your biggest code documentation challenges right now?

    The survey is super-quick and we're offering a $20 discount code for your time (good with any new SubMain product license purchase) that you will automatically receive once you complete the survey as our thank you.

    Take the Survey

    We'd also appreciate it if you'd help us out by tweeting about this using the link Share on Twitter or otherwise letting folks know we're interested to know their code documentation challenges.

    Thanks for your help!

  • Elements of Helpful Code Documentation

    If you spend enough years writing software, sooner or later, your chosen vocation will force you into reverse engineering.  Some weird API method with an inscrutable name will stymie you.  And you'll have to plug in random inputs and examine the outputs to figure out what it does.

    blog-elements-of-helpful-code-documentationClearly, this wastes your time.  Even if you enjoy the detective work, you can't argue that an employer or client would view this as efficient.  Library and API code should not require you to launch a mystery investigation to determine what it does.

    Instead, such code should come with appropriate documentation.  This documentation should move your focus from wondering what the code does to contemplating how best to leverage it.  It should make your life easier.

    But what constitutes appropriate documentation?  What particular characteristics does it have?  In this post, I'd like to lay out some elements of helpful code documentation.

    Elements of Style

    Before moving on to what the documentation should contain, I will speak first about its stylistic properties.  After all, poorly written documentation can tank understanding, even if it theoretically contains everything it should.  If you're going to write it, make it good.

    Now don't get me wrong -- I'm not suggesting you should invest enough time to make it a literary masterpiece.  Instead, focus on three primary characteristics of good writing: clarity, correctness, and precision.  You want to make sure that readers understand exactly what you're talking about.  And, obviously, you cannot get anything wrong.

    The importance of this goes beyond just the particular method in question.  It affects your entire credibility with your userbase.  If you confuse them with ambiguity or, worse, get something wrong, they will start to mistrust you.  The documentation becomes useless to them and your reputation suffers.


    Once you've gotten your house in order with stylistic concerns in the documentation, you can decide on what to include.  First up, I cannot overstate the importance of including examples.

    Whether you find yourself documenting a class, a method, a web service call, or anything else, provide examples.  Show the users the code in action and let them apply their pattern matching and deduction skills.  In case you hadn't noticed, programmers tend to have these in spades.

    Empathize with the users of your code.  When you find yourself reading manuals and documentation, don't you look for examples?  Don't you prefer to grab them and tweak them to suit your current situation?  So do the readers of your documentation.  Oblige them. (See <example />)


    Next up, I'll talk about the general consideration of "conditions."  By this, I mean three basic types of conditions: preconditions, postconditions, and invariants.

    Let me define these in broad terms so that you understand what I mean.  Respectively, preconditions, postconditions, and invariants are things that must be true before your code executes, things that must be true after it executes, and things that must remain true throughout.

    Documenting this information for your users saves them trial and error misery.  If you leave this out, they may have to discover for themselves that the method won't accept a null parameter or that it never returns a positive number.  Spare them that trial and error experimentation and make this clear.  By telling them explicitly, you help them determine up front whether this code suits their purpose or not. (See <remarks /> and <note />)

    Related Elements

    Moving out from core principles a bit, let's talk about some important meta-information.  People don't always peruse your documentation in "lookup" mode, wanting help about a code element whose name they already know.  Instead, sometimes they will 'surf' the documentation, brainstorming the best way to tackle a problem.

    For instance, imagine that you want to design some behavior around a collection type.  Familiar with List, you look that up, but then maybe you poke around to see what inherits from the same base or implements the same interface.  By doing this, you hope to find the perfect collection type to suit your needs.

    Make this sort of thing easy on readers of your documentation by offering a concept of "related" elements.  Listing OOP classes in the same hierarchy represents just one example of what you might do.  You can also list all elements with a similar behavior or a similar name.  You will have to determine for yourself what related elements make sense based on context.  Just make sure to include them, though. (See <seealso /> )

    Pitfalls and Gotchas

    Last, I'll mention an oft-overlooked property of documentation.  Most commonly, you might see this when looking at the documentation for some API call.  Often, it takes the form of "exceptions thrown" or "possible error codes."

    But I'd like to generalize further here to "pitfalls and gotchas."  Listing out error codes and exceptions is great because it lets users know what to expect when things go off the rails.  But these aren't the only ways that things can go wrong, nor are they the only things of which users should be aware.

    Take care to list anything out here that might violate the principle of least surprise or that could trip people up.  This might include things like, "common ways users misuse this method" or "if you get output X, check that you set Y correctly."  You can usually populate this section pretty easily whenever a user struggles with the documentation as-is.

    Wherever you get the pitfalls, just be sure to include them.  Believe it or not, this kind of detail can make the difference between adequate and outstanding documentation.  Few things impress users as much as you anticipating their questions and needs. (See <exception />, <returns /> and <remarks />)

    Documentation Won't Fix Bad Code

    In closing, I would like to offer a thought that returns to the code itself.  Writing good documentation is critically important for anyone whose code will be consumed by others -- especially those selling their code.  But it all goes for naught should you write bad or buggy code, or should your API present a mess to your users.

    Thus I encourage you to apply the same scrutiny to the usability of your API that I have just encouraged you to do for your documentation.  Look to ensure that you offer crisp, clear abstractions.  Name code elements appropriately.  Avoid surprises to your users.

    Over the last decade or so, organizations like Apple have moved us away from hefty user manuals in favor of "discoverable" interfaces.  Apply the same principle to your code.  I tell you this not to excuse you from documentation, but to help you make your documentation count.  When your clean API serves as part of your documentation, you will write less of it, and what you do write will have higher value to readers.

    Learn more about how GhostDoc can help simplify your XML Comments, produce and maintain quality help documentation.

    About the Author

    Erik Dietrich

    I'm a passionate software developer and active blogger. Read about me at my site. View all posts by Erik Dietrich

  • Generate Documentation from Your Build

    Before I get down to the brass tacks of how to do some interesting stuff, I'm going to spin a tale of woe.  Well, I might have phrased that a little strongly.  Call it a tale of corporate drudgery.

    In any case, many years ago I worked briefly in a little department, at a little company that seemed to be a corporate drudgery factory.  Oh, the place and people weren't terrible.  But the work consisted of, well, drudgery.  We 'consulted' in the sense that we cranked out software for other companies, for pay.  Our software plumbed the lines of business between client CRMs and ERPs or whatever.  We would write the software, then finish the software, then hand the software over, source code and all.

    Naturally, commenting our code and compliance with the coding standard attained crucial importance.  Why?  Well, no practical reason.  It was just that clients would see this code.  So it needed to look professional.  Or something.  It didn't matter what the comments said.  It didn't matter if the standard made sense.  Compliance earned you a gold star and a move onto the next project.

    As I surveyed the scene surrounding me, I observed a mountain of vacuous comments and dirty, but uniform code.

    My Complex Relationship with Code Comments

    My brief stay with (and departure from) this organization coincided with my growing awareness of the Software Craftsmanship movement.  Even as they copy and pasted their way toward deadlines and wrote comments announcing that while(x < 6) would proceed while x was less than 6, I became interested in the idea of the self-documenting code.

    Up to that point, I had diligently commented each method, file, and type I encountered.  In this regard, I looked out for fellow and future programmers.  But after one too many occasions of watching my own comments turn into lies when someone changed the code without changing the comments, I gave up.  I stopped commenting my code, focusing entirely on extractions, refactoring, and making my code as legible as possible.

    I achieved an equilibrium of sorts.  In this fashion, I did less work and stopped seeing my comments become nasty little fibs.  But a single, non-subtle flaw remained in this absolutist approach.  What about documentation of a public (or internal) API?

    Naturally, I tried to apply the craftsmanship-oriented reasoning unilaterally.  Just make the public API so discoverable as to render the issue moot.  But that never totally satisfied me because I still liked my handy help screens and IntelliSense info when consuming others' code.

    And so I came to view XML doc comments on public methods as an exception.  These, after all, did not represent "comments."  They came packaged with your deliverables as your product.  And I remain comfortable with that take today.

    Generating Help More Efficiently

    Now, my nuanced evolved view doesn't automatically mean I'll resume laboriously hand-typing XML comments.  Early in my career, a sort of sad pride in this "work harder, not smarter" approach characterized my development.  But who has time for that anymore?

    Instead, with a little bit of investment in learning and tooling, you can do some legitimately cool stuff.  Let me take you through a nifty sequence of steps that you may come to love.

    GhostDoc Enterprise

    First up, take a look at the GhostDoc Enterprise offering.    Among other things, this product lets you quickly generated XML comments, customize the default generation template, spell check your code, generate help documentation and more.  Poking through all that alone will probably take some time out of your day.  You should download and play with the product.

    Once you are done with that, though, consider how you might get more efficient at beefing up your API.  For the rest of this post, I will use as an example my Chess TDD project.  I use this as a toy codebase for all kinds of demos.

    I never commented this codebase, nor did I generate any kind of documentation for it.  Why?  I intended it solely as a teaching tool for test-driven development, and never packaged it for others' consumption.  Let's change that today.

    Adding Comments

    Armed with GhostDoc enterprise, I will first generate some comments.  The Board class makes a likely candidate since that offers theoretical users the most value.

    First up, I need to add XML doc comments to the file.  I can do this by right clicking in the file, and selecting "Document Type" from the GhostDoc Enterprise context menu.  Here's what the result looks like.


    The default template offers a pretty smart guess at intent, based on good variable naming.  For my fellow clean code enthusiasts out there, you can even check how self-documenting your code is by the quality of the comments GhostDoc creates.  But still, you probably want to take a human pass through, checking and tweaking where needed.

    Building Help Documentation

    All right.  With comments in place for the public facing API of my little project, we can move on to the actual documentation.  Again, easy enough.  Select "Tools -> GhostDoc Enterprise -> Build Help Documentation" from the main menu.  You'll see this screen.


    Notice that you have a great deal of control over the particulars.  Going into detail here is beyond the scope of my post, but you can certainly play around.  I'll take the defaults and build a CHM help file.  Once I click "OK", here's what I see (once I go to the board class).


    Pretty slick, huh?  Seriously.  With just a few clicks, you get intelligently commented public methods and a professional-looking help file.  (You can also have this as web-style documentation if you want).  Obviously, I'd want to do some housekeeping here if I were selling this, but it does a pretty good job even with zero intervention from me.

    Do It From the Build

    Only one bit of automation remains at this point.  And that's the generation of this documentation from the build.  Fortunately, GhostDoc Enterprise makes that simple as well.

    Any build system worth its salt will, of course, let you hook command line invocations into your build.  GhostDoc Enterprise offers one up for just this occasion.  You can read a succinct guide on that right here.  With a single command, you can point it at your solution, a help configuration, and a project configuration, and generate the help file.  Putting it where you want is then easy enough.

    Tying this in with an automated build or CI setup really ties everything together, including the theme of this post.  Automating the generation of clean, helpful documentation of your clean code, building it, and packaging it up all without human intervention pretty much represents the pinnacle of delivering a professional product.

    Learn more about how GhostDoc can help simplify your XML Comments, produce and maintain quality help documentation.

    About the Author

    Erik Dietrich

    I'm a passionate software developer and active blogger. Read about me at my site. View all posts by Erik Dietrich

  • Released: GhostDoc v5.3 update

    Version 5.3 of GhostDoc is a maintenance update for the v5.0 users:

    • Added full support for string interpolation in C# and VB parsers
    • Added support for "arrow functions" in JavaScript parser
    • Fixed "File is not part of a solution" issue when loading projects
    • (Pro) (Ent) Added IsAbstract property to CurrentCodeElement in the T4 templates
    • Improved exception documentation - now the type name in a nameof() parameter is added as part of the generated documentation template
    • (Ent) Fixed iue when using <section> along with <code> elements in an .aml file

    For the complete list of changes, please see What's New in GhostDoc v5

    For overview of the v5.0 features, visit Overview of GhostDoc v5.0 Features

    Download the new build at

  • What's in a Name? Spelling Matters in Code

    Think back to college (or high school, if applicable).  Do you remember that kid that would sit near the front of the class and gleefully point out that the professor had accidentally omitted an apostrophe when writing notes on the white board?  Didn't you just love that kid?  Yeah, me neither.

    Fate imbues a small percentage of the population with a neurotic need to correct any perceived mistakes made by anyone.  XKCD immortalized this phenomenon with one of its most famous cartoons, that declared, "someone is wrong on the internet."  For the rest of the population, however, this tendency seems pedantic and, dare I say, unpleasant.  Just let it go, man.  It doesn't matter that much.

    I mention all of this to add context to the remainder of the post.  I work as a consultant and understand the need for diplomacy, tact, and choosing one's battles.  So, I do not propose something like care with spelling lightly.  But I will propose it, nonetheless.

    Now I know what you're thinking.  How can caring about spelling in code be anything but pedantic?  We're not talking about something being put together to impress a wide audience, like a newspaper.  In fact, we're not even talking about prose.  And code contains all sorts of abbreviations and encodings and whatnot.

    Nevertheless, it matters.  When English words occur in your code, spelling them right matters.  I'll use the rest of this post to make my case.

    The IntelliSense Conundrum

    If you use Visual Studio, no doubt you make heavy use of IntelliSense.  To expand, any IDE or text editor with autocomplete functionality qualifies for consideration here.  In either case, your tooling gives you a pretty substantial boost by suggesting methods/variables/classes/etc based on what you have typed.  It's like type-ahead for code.

    Now think of the effect a misspelling can have here, particularly near the beginning of a word.  Imagine implementing a method that would release resources and accidentally typing Colse instead of Close.  Now imagine consuming that method.  If you're used to exploring APIs and available methods with auto-complete, you might type, "Clo", pause, and see no matching methods.  You might then conclude, "hey, no call to Close needed!"

    In all likelihood, such an error would result in a few minutes of head-scratching and then the right call.  But even if that's the worst of it, that's still not great.  And it will happen each and every time someone uses your code.

    Other Manual Typing Errors

    The scope of this particular issue goes beyond auto-complete functionality.  Perhaps you lack that functionality in your environment, or perhaps you simply don't use it much.  In that case, you'll be hand typing your code.

    Now, imagine hand typing the call above to a close method.  Do you instinctively type "Colse" or do you instinctively type "Close?"  So what do you think will happen?

    You'll expect the call to be Close and you'll type that.  Then, you'll stare in disbelief for a moment at the compiler message.  You'll probably do a clean and rebuild.  You'll stare again for a while and squint.  Then, finally, you'll smack your forehead, realize the problem, and silently berate the person who misspelled the method name.

    Again, the impact remains the same.  Most likely this creates only friction and annoyance.  Every now and then, it may trigger a thoroughly incorrect use of a library or API.

    Anchoring Effect

    Moving away from the theme of confusion when using a declared member, consider the declaration itself.  During the use of a variable/method/class/etc, you must spell it right before the compiler allows you to proceed (assuming a strongly typed language).  With the original declaration, however, you have the freedom to spell things wrong to your heart's content.  When you do this, the original copy holds the error.

    That first misspelling allows for easy correction.  Same goes when you've used it only a time or two.  But as usage grows and spreads throughout the codebase, the fix becomes more and more of a chore.  Before long (and without easy refactoring tools), the chore becomes more than anyone feels like tackling, and the error calcifies in place.

    Your unaddressed spelling mistake today makes fixes more difficult tomorrow.

    Comprehension Confusion

    Let's switch gears again and consider the case of a maintenance programmer reading for comprehension.  After all, programmers do a whole lot more reading of code than they do modification of it.  So, a casual read is a likely situation.

    Spelling errors cloud comprehension.  A simple transposition of characters or a common error, such as referring to a "dependency" do not present an insurmountable problem.  But a truly mangled word can leave readers scratching their heads and wondering what the code actually means, almost as if you'd left some kind of brutal Hungarian notation in there.

    Taking the time to get the spelling right ensures that anyone maintaining the code will not have this difficulty.  Code is hard enough to understand, as-is, without adding unforced errors to the mix.

    The Embarrassment Factor

    And, finally, there's the embarrassment factor.  And I don't mean the embarrassment of your coworkers saying, "wow, that guy doesn't know how to spell!"  I'm talking about the embarrassment factor for the team.

    Think of new developers hiring on or transferring into the group.  They're going to take a look at the code and draw conclusions, about your team.  Software developers tend to have exacting, detail-oriented minds, and they tend to notice mistakes.  Having a bunch of spelling mistakes in common words makes it appear either that the team doesn't know how to spell or that it has a sloppy approach.  Neither of those is great.

    But also keep in mind that what happens in the code doesn't always stay in the code.  Bits of the code you write might appear on team dashboards, build reports, unit test run outputs, etc.  People from outside of the team may be examining acceptance tests and the like.  And, you may have end-user documentation generated automatically using your code (i.e. if you make developer tools or APIs).  Do you really want the documentation you hand to your customers to contain embarrassing mistakes?

    It's Easy to Get Right

    At this point, I'm finished with the supply of arguments for making the case.  I've laid these out.

    But, by way of closing words, I'd like to comment on what might be the biggest shame of the whole thing.  Purging your code of spelling errors doesn't require you to be an expert speller.  It doesn't require you to copy source code into MS Word or something and run a check.  You have tools at your disposal that will do this for you, right in your IDE.  All you need to do is turn them on.

    I recommend that you do this immediately.  It's easy, unobtrusive, and offers only upside.  And not only will you excise spelling mistakes from your code -- you'll also prevent that annoying kid in the front of the class from bothering you about stuff you don't have time for.

    Learn more about GhostDoc's truly source code spell checker and eliminate embarrassing typos in your apps and documentation before you ship them.

    About the Author

    Erik Dietrich

    I'm a passionate software developer and active blogger. Read about me at my site. View all posts by Erik Dietrich

  • Comments in Clean Code? Think Documentation

    Notwithstanding some oddball calculator and hobby PC hacking, my first serious programming experience came in college.  A course called "Intro to C++" got us acquainted with arrays, loops, data structures and the like.  Given its introductory nature, this class did not pose a particularly serious challenge (that would come later).  So, with all of the maturity generally possessed by 18 year olds, we had a bit of fun.

    I recall contests to see how much application logic we could jam into the loop conditions, and contests to see how much code could be packed onto one line.  These sorts of scavenger hunt activities obviously produced dense, illegible code.  But then, that was kind of the point.

    Beyond these silly hijinks, however, a culture of code illegibility permeated this (and, I would learn later) other campuses.  Professors nominally encouraged code readability.  After all, such comments facilitated partial credit in the event of a half-baked homework submission.  But, even still, the mystique of the ingenious but inscrutable algorithm pervaded the culture both for students and faculty.  I had occasion to see code written by various professors, and I noticed no comments that I can recall.

    Professionalism via Thoroughness

    When I graduated from college, I carried this culture with me.  But not for long.  I took a job where I spent most of my days working on driver and kernel module programming.  There, I noticed that the grizzled veterans to whom I looked up meticulously documented their code.  Above each function sat a neat, orderly comment containing information about its purpose, parameters, return values, and modification history.

    This, I realized, was how professionals conducted themselves.  I was hooked.  Fresh out of college, and looking to impress the world, I sought to distinguish myself from my undisciplined student ways.  This decision ushered in a period of many years in which I documented my code with near religious fervor.

    My habit included, obviously, the method headers that I emulated.  But on top of that, I added class headers and regularly peppered my code with line comments that offered such wisdom as "increment the loop counter until the end of the array."  (Okay, probably not that bad, but you get the idea).  I also wrote lengthy readme documents for posterity and maintenance programmers alike.  My professionalism knew no bounds.

    Clean Code as Plot Twist

    Eventually, I moved on from that job, but carried my habits with me.  I wrote different code for different purposes in different domains, but stayed consistent in my commenting diligence.  This I wore as a badge of pride.

    While I was growing in my career, I started to draw inspiration from the clean code movement.  I began to write unit tests, I practiced the SOLID principles, I watched Uncle Bob talks, made my methods small, and sought to convince others to do the same.  Through it all, I continued to write comments.

    But then something disconcerting happened.  In the clean code circles I followed and aspired to, I started to see posts like this one.  In it, the author had written extensively about comments as a code smell.

    Comments are a great example of something that seems like a Good Thing, but turn out to cause more harm than good.

    For a while, I dismissed this heresy as an exception to the general right-thinking of the clean code movement.  I ignored it.  But it nagged at me nonetheless, and eventually, I had to confront it.

    When I finally did, I realized that I had continued to double down on a practice simply because I had done it for so long.  In other words, the extensive commenting represented a ritual of diligence rather than something in which I genuinely saw value.

    Down with Comments

    Once the floodgates had opened, I did an about-face.  I completely stopped writing comments of any sort whatsoever, unless it was part of the standard of the group I was working with.

    The clean coder rationale flooded over me and made sense.  Instead of writing inline comments, make the code self-documenting.  Instead of comments in general, write unit and acceptance tests that describe the desired behaviors.  If you need to explain in English what your code does, you have failed to explain with your code.

    Probably most compelling of all, though, was the tendency that I'd noticed for comments to rot.  I cannot begin to estimate how many times I dutifully wrote comments about a method, only to return a year later and see that the method had been changed while the comments had not.  My once-helpful comments now lied to anyone reading them, making me look either negligent or like an idiot.  Comments represented duplication of knowledge, and duplication of knowledge did what it always does: gets out of sync.

    My commenting days were over.

    Best of All Worlds

    That still holds true to this day.  I do not comment my code in the traditional sense.  Instead, I write copious amounts of unit, integration and acceptance tests to demonstrate intent.  And, where necessary and valuable, I generate documentation.

    Let's not confuse documentation and commenting.  Commenting code targets maintenance programmers and team members as the intended audience.  Documenting, on the other hand, targets external consumers.  For instance, if I maintained a library at a large organization, and other teams used that library, they would be external consumers rather than team members.  In effect, they constitute customers.

    If we think of API consumers as customers, then generating examples and documentation becomes critically important.  In a sense, this activity is the equivalent of designing an intuitive interface for end-users of a GUI application.  They need to understand how to quickly and effectively make the most of what you offer.

    So if you're like me -- if you believe firmly in the tenets of the clean code movement -- understand that comments and documentation are not the same thing.  Also understand that documentation has real, business value and occupies an important role in what we do.  Documentation may take the form of actual help documents, files, or XML-doc style comments that appear in IntelliSense implementations.

    To achieve the best of all worlds, avoid duplication.  Make publishing documentation and examples a part of your process and, better yet, automate these activities.  Your code will stay clean and maintainable and your API users will be well-informed and empowered to use your code.

    Learn more about how GhostDoc can help simplify your XML Comments, produce and maintain quality help documentation.

    About the Author

    Erik Dietrich

    I'm a passionate software developer and active blogger. Read about me at my site. View all posts by Erik Dietrich

More Posts Next page »

This Blog


Home |  Products |  Services |  Download |  Purchase |  Support |  Community |  About Us |