What are the best practices when using global variables?
Normally, the common answer to this is to avoid using global variables and use local variables, properties and arguments to pass data around. However, I'm working with a domain specific language that does not support these concepts.
In the language I'm using, there are procedures, and the only mechanism for passing parameters to them is to define a global variable - something like:
def x def y sub main set x = 100 call foo -- prints 100 set y = 5 call baa print y -- prints 10 call baa print y -- prints 20 end sub foo -- Really, the ideal signature would be `void foo(x)` print x end sub baa -- Really, the ideal signature would be `int baa(ref y)` set y = y * 2 end
Given this will tend to cause confusion for all the normal reasons to avoid globals, what can be done to ensure the code is of high quality, still readable, reliable, or any other concerns I've not listed but are normal things to think about?
Some items I've considered
- Every procedure adds its own name as a prefix to its arguments, so the above would be named foo_x when passed to foo, but this means lots of additional declarations if I want to pass the same variable to multiple procedures
- Keep documentation of every variable somewhere and consult it when deciding on a new variable (possibly with some sort of Hungarian notation)
- Document which method "owns" which variable and do not change it outside that scope (to try to simulate variables being local to a method, and only ever passed by value), so the above would be named main_x
- A combination of these, something like:
def main_x -- local variable x for main method def foo_x -- argument to foo method def main_y -- local variable y for main method def baa_y -- argument to y method, should be passed by reference sub main set main_x = 100 -- set up initial value of x set foo_x = main_x -- prepare to call foo call foo set main_y = 5 -- set initial value of y set baa_y = main_y -- prepare to call baa (first time) call baa set main_y = baa_y -- get the result of baa print main_y set baa_y = main_y -- prepare to call baa (second time) call baa set main_y = baa_y print main_y end sub foo print foo_x end sub baa set baa_y = baa_y * 2 end
This approach means the functions don't need to know about each other and can have distinct variable names, but it starts to get quite complicated to read.