3 ms·
Are they really? I agree that global variables are horrible in a language like C where they are truly “global” because of the lack of namespaces. But in a langu
by __sr__ 8y ago
Are they really? I agree that global variables are horrible in a language like C where they are truly “global” because of the lack of namespaces. But in a language like Python, they are tolerable because they are not truly global — they are restricted to the particular module. I am not saying they are great, but they are not as horrible as they are in, say, C. Of course, care must be taken to ensure that they are abused, but that is true of any programming construct.
If module global variables are considered truly horrible, the same can be said about instance variables inside classes. They are as good (or bad) as module globals in the sense that they represent shared state and can potentially be mutated by any method/member function in the class.
Of course the functional programmers among us will say that shared state of any kind is bad, and I agree. But we are not talking about that here, are we?
- LolNoGenerics 8y agoI don't think anyone argues variables with module scope. Because as you say they are not global.
- __sr__ 8y agoWell, there have been cases where I was asked to get rid of them by people reviewing my code — for no reason other than that global variables are “considered harmful”.
- cakoose 8y agoMutable variable that have exactly one instance (globally) cause some of the same issues, which is why people might casually lump them in with "global variables". (It would be nice if everyone used more precise terminology, though.)
- nine_k 8y agoSome modules are unlike others. Try setting `sys.stdout` in one extremely local function, observe ripples everywhere. It's not common, fortunately; hacking `sys.path` is more common, and is sometimes done at import time. With all its upsides, Python has a problematic global state story; it's easy to shoot yourself in the foot.
- __sr__ 8y agoI am not saying that python globals are a great idea — just that they are not as horrible as they are in case of C and they they do have their uses — they just need to be used carefully. Of course, python makes it impossible to truly hide anything. In an ideal world, module level globals won’t be mutable outside the module.
- mpartel 8y agoMutable instance variables are much less bad because their scope is much more limited: you can much more easily scan all the code that mutates them and check that invariants are upheld etc. Global mutable variables are also awful for multithreading. Thread-locals help, but even they breaks horribly as soon as you use something like a thread pool.
- __sr__ 8y ago> Mutable instance variables are much less bad because their scope is much more limited: you can much more easily scan all the code that mutates them and check that invariants are upheld etc. Same can be done with module level globals.
- mpartel 8y agoYou're right, assuming the module is not too large. There's another point in favor of instance variables: it gives you the flexibility of multiple values in different parts of your code. As codebases grow, the danger of two unrelated places wanting different values for your global also grows. Say a physics simulation has a global for gravity. This precludes, or at least unnecessarily complicates, the same process from having two separate simulations with different gravities (perhaps in different threads). This is especially bad in library code.
- __sr__ 8y agoAgreed, and module globals shouldn’t be used for such cases. But for simpler cases, it may, in some cases, be better to use globals than create a singleton or some other convoluted solution. To be clear, I am not saying globals should be used everywhere. There are a programming construct just like any other. When used carefully, they can greatly simplify code — but also have the potential to horribly complicate the code when abused. And that is true about any programming construct. One thing that irritates me is the tendency to paint things black and white — eg. goto, globals, multiple inheritance etc. are bad. So “modern” programming languages try to eliminate them in a misguided attempt to keep programmers safe from themselves. I agree that these things are often misused, but a bad programmer will figure out a way to misuse anything — or do you think it is impossible to write bad code in something like, say, Go? Dumbing things down doesn’t prevent bad programmers from messing up, instead it causes the rest to write horrible code because of the lost power.
- nothrabannosir 8y agoAny time I come across (or review) code which uses globals, even at the module level, they invariably make it hard to mock the related code in tests. Dependency injection and class (/instance) level state are an improvement pretty much always.
- tabs_masterrace 8y agoJust typical zealotry. So instead of globals we should use DependencyInjection, and now the app is magically better? For many projects it hardly matters, and I'm not going to over complicate things when there's no practical reason for it.
- drblast 8y agoAlso modern IDEs change the game a bit. Used to be you wouldn't use globals because it was difficult to figure out what code accessed or changed their values. Now that's a right click away.
- V-2 8y agoIDE will show you where it's accessed, but it's of little use if there are two hundred fifty usages, and IDE won't fix the design choices that followed from the use of globals.
- beobab 8y agoI am still on the fence about them. Yes, they cause problems (looking at you, powershell!). Yes, they can be used as a band-aid for thorny issues (Time constraints!). They are a tool, like any other programming construct. Is making them properties and sticking them in a "GlobalVariablesByAnotherName" singleton and chucking that around better? Possibly. Possibly not. I have found, however, that any code where someone has used global variables is hard to share with other developers. Maybe that's the crux of the matter.
- vaughandroid 8y agoI would say yes they are, in general. The title of the post is an absolute, but as the author says in the second paragraph: > As with all HeuristicRules, this is not a rule that applies 100% of the time. Code is generally clearer and easier to maintain when it does not use globals, but there are exceptions. For me, the root of the problem with them is that they introduce coupling (or to put it another way, they break modularity). When you introduce global state, you introduce it everywhere. In reality there are probably only a handful of places that it relates to, but "is the global state involved here?" becomes a question you need to ask yourself whenever you write/update any part of the code. The same argument can apply at more fine-grained levels. If you introduce a module-level variable, you need to keep it in mind whenever dealing with any code in that module. Similarly for class-level and instance-level variables. There is a trade-off: ease-of-access and clarity vs the extra cognitive load you are introducing to every part of the scope. In my opinion, that balance determines whether a variable is good or bad. For any non-trivial piece of code, the sum almost always works out on the side of reducing the cognitive load.
- cakoose 8y ago> If module global variables are considered truly horrible, the same can be said about instance variables inside classes. They are as good (or bad) as module globals in the sense that they represent shared state and can potentially be mutated by any method/member function in the class. Assuming Python-like modules, module-level globals are worse for encapsulation. 1. A function can access module-level state without having been explicitly passed a reference to it. 2. You can't create additional instances of module-level state. For example, if your app server uses a module-level global for the server listening socket, you can't run two app server instances in the same process.
- __sr__ 8y ago> You can't create additional instances of module-level state. For example, if your app server uses a module-level global for the server listening socket, you can't run two app server instances in the same process. So a global variable should not be used for such cases. That doesn’t mean it is inherently bad. People writing the code are supposed to think about what constructs to use for a given scenario.
- cakoose 8y agoYou said that instance variables were just as bad as module globals. I was pointing out cases (w.r.t. software engineering, obviously, since that is what this thread is about) where module globals are worse. Yes, programmers have to be aware of what they're doing, but that's true of any programming construct. It doesn't mean that we shouldn't identify the dangers.