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.