[In this reprinted #altdevblogaday-opinion piece, CCP's lead technical artist Rob Galanakis rails against the "nefarious criminals of the software industry," global states that mingle with the rest of your code unnoticed.]
I've ripped off this title from a common trend on Raymond Chen of MSFT's blog. Here are a bunch of posts about it.
I can scream it to the heavens but it doesn't mean people understand. Globals are bad. Well, no shit Sherlock. I don't need to write another blog post to say that. What I want to talk about is, what is a global.
It's very easy to see this code and face-palm:
global spam = list() global eggs = dict() global lastIndex = -1But I'm going to talk about much more sinister types of globals, ones that mingle with the rest of your code possibly unnoticed. Globals living amongst us. No longer! Read on to find out how to spot these nefarious criminals of the software industry. Environment Variables There are two classes of environment variable mutation: acceptable and condemning. There is no 'slightly wrong', there's only 'meh, I guess that's OK', and 'you are a terrible human being for doing this.'
- Acceptable use would be at the application level, where environment variables can be get or set with care, as something needs to configure global environment. Acceptable would also be setting persistent environment variables in cases where that is very clearly the intent and it is documented. Don't go setting environment variables willy-nilly, most especially persistent ones!
- Condemning would be the access of custom environment variables at the library level. Never, ever access environment variables within a module of library code (except, perhaps, to provide defaults). Always allow those values to be passed in. Accessing system environment variables in a library is, sometimes, an Acceptable Use. No library code should set an environment variable, ever.
- Commandline use is only acceptable at the entry point of an application. Nothing anywhere else should access the commandline args (except, perhaps to provide defaults).
- Nothing should ever mutate the commandline arguments. Ever!
- at the application level (as a global), and only when absolutely necessary, such as an expensive-to-create object that does not have state. Or:
- in extremely performance-critical areas where there is absolutely no other way. Oh, there's also:
- where you want to write code that is unrefactorable and untestable.