Static Analysis to Hide My Ignorance about Global Concerns
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, take a look at CodeIt.Right to help you automate elements of your code reviews.
“You never concatenate strings. Instead, always use a StringBuilder.”
I feel pretty confident that any C# developer that has ever worked in a group has heard this admonition at least once. This represents one of those bits of developer wisdom that the world expects you to just memorize. Over the course of your career, these add up. And once they do, grizzled veterans engage in a sort of comparative jousting for rank. The internet encourages them and eggs them on.
“How can you call yourself a senior C# developer and not know how to serialize objects to XML?!”
With two evenly matched veterans swinging language swords at one another, this volley may continue for a while. Eventually, though, one falters and pecking order is established.
Static Analyzers to the Rescue
I must confess. I tend to do horribly at this sort of thing. Despite having relatively good memory retention ability in theory, I have a critical Achilles Heel in this regard. Specifically, I can only retain information that interests me. And building up a massive arsenal of programming language “how-could-yous” for dueling purposes just doesn’t interest me. It doesn’t solve any problem that I have.
And, really, why should it? Early in my career, I figured out the joy of static analyzers in pretty short order. Just as the ubiquity of search engines means I don’t need to memorize algorithms, the presence of static analyzers saves me from cognitively carrying around giant checklists of programming sins to avoid. I rejoiced in this discovery. Suddenly, I could solve interesting problems and trust the equivalent of programmer spell check to take care of the boring stuff.
Oh, don’t get me wrong. After the analyzers slapped me, I internalized the lessons. But I never bothered to go out of my way to do so. I learned only in response to an actual, immediate problem. “I don’t like seeing warnings, so let me figure out the issue and subsequently avoid it.”
My Coding Provincialism
This general modus operandi caused me to respond predictably when I first encountered the idea of globalization in language. “Wait, so this helps when? If someone theoretically deploys code to some other country? And, then, they might see dates printed in a way that seems strange to them? Huh.”
For many years, this solved no actual problem that I had. Early in my career, I wrote software that people deployed in the US. Much of it had no connectivity functionality. Heck, a lot of it didn’t even have a user interface. Worst case, I might later have to realize that some log file’s time stamps happened in Mountain Time or something.
Globalization solved no problem that I had. So when I heard rumblings about the “best practice,” I generally paid no heed. And, truth be told, nobody suffered. With the software I wrote for many years, this would have constituted a premature optimization.
But it nevertheless instilled in me a provincialism regarding code.
A Dose of Reality
I’ve spent my career as a polyglot. And so at one point, I switched jobs, and it took me from writing Java-based web apps to a desktop app using C# and WPF. This WPF app happened to have worldwide distribution. And, when I say worldwide, I mean just about every country in the world.
Suddenly, globalization went from “premature optimization” to “development table stakes.” And the learning curve became steep. We didn’t just need to account for the fact that people might want to see dates where the day, rather than the month, came first. The GUI needed translation into dozens of languages as a menu setting. This included languages with text read from right to left.
How did I deal with this? At the time, I don’t recall having the benefit of a static analyzer that helped in this regard. FXCop may have provided some relief, but I don’t recall one way or the other. Instead, I found myself needing to study and laboriously create mental checklists. This “best practice” knowledge hoarding suddenly solved an immediate problem. So, I did it.
CodeIt.Right’s Globalization Features
Years have passed since then. I’ve had several jobs since then, and, as a solo consultant, I’ve had dozens of clients and gigs. I’ve lost my once encyclopedic knowledge of globalization concerns. That happened because — you guessed it — it no longer solves an immediate problem that I have.
Oh, I’d probably do better with it now than I did in the past. But I’d still have to re-familiarize myself with the particulars and study up once again in order to get it right, should the need arise. Except, these days, I could enlist some help. CodeIt.Right, installed on my machine, will give me the heads up I didn’t have those years ago. It has a number of globalization concerns built right in. Specifically, it will remind you about the following concerns. I’ll just list them here, saving detailed explanations for a future “CodeIt.Right Rules, Explained” post.
- Specify culture info.
- Specify string comparison (for culture).
- Do not pass literals as localized parameters.
- Normalize strings to uppercase.
- Do not hard code locale specific strings.
- Use ordinal string comparison.
- Specify marshaling for PInvoke string arguments.
- Set locale for data types.
That provides an excellent head start on getting savvy with globalization.
Throughout the post, I’ve talked about my tendency not to bother with things that don’t solve immediate problems for me. I realize philosophical differences in approach exist, but I stand by this practice to this day. And I don’t say this only because of time savings and avoiding premature optimization. Storing up an arsenal of specific “best practices” in your head threatens to entrench you in your ways and to establish an approach of “that’s just how you do it.”
And yet, not doing this can lead to making rookie mistakes and later repeating them. But, for me, that’s where automated tooling enters the picture. I understand the globalization problem in theory. That I have not forgotten. And I can use a tool like CodeIt.Right to bridge the gap between theory and specifics in short order, creating just-in-time solutions to problems that I have.
So to conclude the post, I would offer the following in takeaway. Stop memorizing all of the little things you need to check for at the method level in coding. Let tooling do that for you, so that you can keep big picture ideas in your head. I’d say, “don’t lose sight of the forest for the trees,” but with tooling, you can see the forest and the trees.