For 10 minutes in the documentation, hours of the time of my customer Papers in systems nice about dynamic conservatism


A recent experience has brought this point home for me: Inadequate documentation wastes the time of everyone.

In Add delimitation between the string elements in C ++I have described the creation of a “comfort function” that simplifies the use of a logger in a client project. When I made this change in the customer’s code base, I added the new implementation and converted some of the existing loggers call. We had already discussed these changes in the problem of Tracker, including examples of how I had imagined it. I also believed that my changes to existing protocol calls would continue to show the use of the function. For these reasons, I thought it was “certain” to cut a corner: I did not write any cutting documentation for the functions.

The change passed the check, so I brought it together and pushed the changes out of my head. A few days later, the client started with the new protocol function. I expected that they would see the sample changes as a reference and that they would remember what we discussed in the problem of Tracker. How naive these expectations were. They returned to the header file to many more natural to look at the functional prototypes.

Then everything didn’t go.

The variadic template syntax was not familiar because the existence of several logging functions of the confusion was added (“What is the right to use?”). They did not understand which valid input argument types were. They sent me some questions, but I only noticed it until it was too late. So the customer made his own research, decided that it was certain to ignore the template version as a whole, and that my intention was that users were packing everything initializer_list<string_view> Variables handed over to the function. Finally I saw my email input and quickly switched the gears over to bring them back on the track.

What a mess. Our customer wasted a few hours that could otherwise have been for progress for progress. I stopped what I was doing to provide support. We both were frustrated. All just because I have forwarded Ten minutes Documentation letter.

Let that be a lesson.

/** System Logging Interface
 *
 * There are three primary function variations that you will use:
 * - logLine, which simply takes an already-formatted string and writes it to the file as-is
 * - logEngLine(component_id, args...), which formats the supplied variadic argument list into
 *    the appropriate engineering log format.
 *     @code
 *     Logger::logEngLine(VERBOSE, "param1", "param2", string_param);
 *     @endcode
 *
 * The general format of a logged engineering line is:
 * - STX + component_id + DELIM + timestamp + DELIM + current state + ((DELIM + args)...) + ETX
 */
class Logger
{
  // ... elided details
  
  /** Save a line to the log file without further modification.
   *
   * This logging function should be used to write contents to the log file.
   * Unlike logEngLine, this function does not modify the supplied contents or
   * coerce them into any special format.
   *
   * @pre Logger module has been initialized
   * @post Input line has been logged to the currently open log file without
   *  further modification.
   *
   * @param verbosity (in) Verbosity level of the log statement.
   * @param line (in) The string contents to write to the log file.
   */
    static unsigned logLine(LogLevels verbosity, const std::string_view line);

  /** Logger "worker" function
   *
   * This function does the work of taking a list of string arguments and
   * formatting them into the proper engineering line format, e.g.,
   * (STX)param1(delimiter)param2(delimiter)param3(ETX).
   *
   * The actual formatting is controlled by the implementation of this function.
   *
   * Users are not required to invoke this function unless it is desired
   * to use a std::initializer_list. Instead the templated logEngLine variant
   * is intended to be used - this will coerce all the arguments into a list
   * and invoke this function.
   *
   * If you wish to use this version, parameters can be suppiled either with an
   * initializer_list variable, or in the following manner:
   * @code
   * Logger::logEngLine(VERBOSE, {"param1", "param2", string_param});
   * @endcode
   *
   * @pre Logger module has been initialized
   * @post Arguments have been formatted into engineering line format and saved
   *  to the currently open log file.
   *
   * @param verbosity (in) Verbosity level of the log statement.
   * @param args (in) List of arguments to format into an engineering log
   *
   * @input A std::initializer_list of string_view arguments that
   */
  static void logEngLine(LogLevels verbosity, const std::initializer_list<std::string_view> args);

  /** Log a list of parameters in engineering line format.
   *
   * This function does the work of taking a list of arguments and putting them
   * into the target enginering line format, such as:
   *  (STX)param1(delimiter)param2(delimiter)param3...(ETX).
   *
   * The actual formatting is controlled by the std::initializer_list variation
   * of logEngLine. This function is invoked like:
   *
   * @code
   * Logger::logEngLine(VERBOSE, "param1", "param2", string_param);
   * @endcode
   *
   * @pre Logger module has been initialized
   * @post Arguments have been formatted into engineering line format and saved
   *  to the currently open log file.
   *
   * @param (in) vs... Variadic list of values that are to be logged in engineering
   * line format. The parameters can be any type that can be implicitly converted
   * to std::string_view, including:
   *  - const char*
   *  - char()
   *  - std::string
   *  - std::string_view
   */
  template<typename... Values>
  static inline void logEngLine(LogLevels verbosity, Values const&... vs )
  {
      logEngLine(verbosity, {vs...});
  }
};

References



Source link