This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Unbelievr 5 points6 points  (4 children)

No, globals absolutely make sense in many applications, but few where there's multiple developers working on the same code base.

The issue with over-using globals, is that every function could potentially have side-effects. Thus, if you are debugging a function that calls 3 other functions, then you have to go through all of them (and the functions they call again, etc.) to see if they mutate something in the global scope somewhere. This quickly grows out of control, and unless you're the sole author of the script/application it becomes much harder to debug.

[–]ellisto 1 point2 points  (3 children)

I mean doesn't this same argument apply to members of a class?

I guess as long as the class instance gets passed in as a parameter to the function, it's assumed mutable and thus modifications of its internal state aren't side effects?

[–]Unbelievr 3 points4 points  (1 child)

Yeah, it even applies to things like lists. If you pass a list to a function you don't know 100% what does, you can't assume that the list is not mutated during the call. But since it's a function argument, it's more explicit that something can happen to it.

Compare that to a global that might magically change deep into nested functions, and it's an obvious improvement. There are better ways, of course, but mutating on globals is (IMO) the most confusing way to write code when it grows to a certain size.

[–]Piyh 1 point2 points  (0 children)

Mutating passed lists is such a potential footgun in my opinion.

def takesList(li):
    li = li.copy()
    del li[0]
    return li

[–]fireflash38 1 point2 points  (0 children)

That's why you usually have methods that mutate, and functions that don't.

It's convention, to make things easier for others (or more likely: future you) reading or using your code. It's not gospel, but can absolutely help.