Posts

Showing posts from September, 2023

Commands and the STL

Consider the following classic (so classic I'm presenting it in C++03 terms) execution model: std::map<int, IFunctor*> CommandMap; Where the IFunctor interface has a virtual method virtual void process(const Message& inMessage) = 0; That's basically the substructure of a command pattern, if we assume that the Message class has int getMessageType() const; as a function. There's a potential problem. What if your data to be processed has to be analyzed not by some nice comparable key, but by a complex of conditions, where the characteristics looked at are variable, although either the conditions are exclusive - no two can be true if the same message - or they can be strictly ranked. Thus, say, the message is analyzed based on the client associated with it or the money associated with it, or the jurisdiction it is from, or a combination of the three. (E.g. the first priority condition might be "Client is a PEP", then, "Transaction is for over 100,000 an...

Code Reviews

One of the most pernicious lines I have seen in chat in a professional coding context is: "I need someone else to approve my code before it can be promoted". No, you need someone to review your code. Approval is not to be assumed. Indeed, on general principles, it would probably be better to assume that on the first try there will be changes requested. Code reviews are not there to get code checked in. They are not even there (only) to catch potential bugs. They are there to ensure that code is not only algorithmically correct but maintainable, tested, and has no other issues. ("No other issues" includes things like: "That function you extracted is applicable in these other areas of the code base. It should be moved to a more general library and applied to the other places" or, more seriously: "You have introduced a cyclic dependency between packages.") I have come to view the code reviewing model implicitly promoted by the Atlassian tools and gi...

Small utilities, other languages

Sometimes, all you want is a small, stand-alone utility. I strongly recommend J. Guy Davidson and Kate Gregory's Beautiful C++: 30 Core Guidelines for Writing Clean, Safe, and Fast Code , which is an expansion of some of the more important C++ core guidelines (available at https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines ).  I got to thinking: the guidelines are small, useful blocks of text.  The website is designed for browsing, but they support a cookie-style type of accessing as individual blocks as well.  Why not produce a small utility which can take a downloaded version and extract guidelines by their reference number (e.g. F.1 for "The first guideline in Functions") or (in a cookie-style manner) randomly? C++ is overkill for something this small, which is essentially small bits of text manipulation. So I decided to use go instead.  The whole utility is under 400 lines of code. So let's start by looking from the top down.  Here's main(): 0 fun...

Revisiting the command line: simple options

Sometimes, you don't want a full-fledged standardized way of accessing options. I wrote a quick utility to do a local LT lookup based on the previously created library, withthe aim of generating citations which could be put into documents I was writing in emacs. It has several command line parameters but only two options (produce italic formatting in HTML or LaTeX; select between bibliographic and footnote formatting). The rest of the parameters are just: the first value is the author's last name, any subsequent parameters are words from the title. The options may be anywhere. The original command-line LT application used the CommandLineOptions class from my general utilities. That class isn't really meant for this sort of command line, though. We don't want to walk a set of positional arguments, because we don't have a defined order. The author name might be argument 1, 2, or 3. If there are options they might be at the end (does not affect the order otherwise),...

Thinking About Documenting Code

Writing about the interaction of objects in an effective way is not necessarily straightforward. At a general object design level, one wants to talk about objects as block-box collaborators, and usually in terms of modelling actions. At a level of talking about programming details, one usually wants to look inside  a specific object and discuss the way in which pieces of data (frequently data members, not black-box objects) are wired together algorithmically. These two types of interest barely intersect. Let me take a small concrete example to illustrate. I have a very small utility class called PathHandler.  If we want to talk about it as a black box, we look at its interface:   PathHandler(const std::string &inEnvVariable);   void process(std::function<void(const std::string &)> inFunc) const;   void processUntilMatch(std::function<bool(const std::string &)> inFunc) const;   bool empty() const { return m_members.empty(); } The cons...