Page 1 of 1

Can't create global variables inside function per documentation

Posted: 16 Jan 2017, 00:42
by pneumatic
From the documentation:
Global variables

To refer to an existing global variable inside a function (or create a new one), declare the variable as global prior to using it.
Assume-global mode: If a function needs to access or create a large number of global variables, it can be defined to assume that all its variables are global (except its parameters) by making its first line either the word "global" or the declaration of a local variable.
However I am finding neither of these methods work. Here is an example:

Code: Select all

#Persistent
function1()
function2()
return

function1(){
global variable := 1        ;or global [line feed] variable :=1
}

function2(){
msgbox %variable%
}
The messagebox is blank.

The only way to do it is to define variable as global in the autoexecute section, but that is untidy and difficult to keep track of. I only want to declare global variables inside the function I am working in. Is there any way to do it?

Re: Can't create global variables inside function per documentation

Posted: 16 Jan 2017, 01:45
by lexikos
If you think that is not creating a global variable, you are mistaken. This is no bug.

Code: Select all

function1()
function2()

function1(){
global variable := 1  ; Creates a global variable.
ListVars
MsgBox
}

function2(){
ListVars
msgbox %variable%  ; Refers to an uninitialized local variable.
}
Variables access or created inside a function are local by default
https://autohotkey.com/docs/Functions.htm#Locals
pneumatic wrote: I only want to declare global variables inside the function I am working in.
You want the language to work differently to how it does. That's too bad, unless you want to learn C++ and change the language yourself.

Variables do not need to be declared in the auto-execute section. For a global variable to be automatically visible in every function, it must be declared outside of every function - anywhere not in a function. Declarations do not need to be "evaluated" - they are not subject to control flow. Therefore, you can simply declare the variables above the function.

Code: Select all

function1()
function2()
return

global variable
function1(){
variable := 1
ListVars
MsgBox
}

function2(){
ListVars
msgbox %variable%
}
However, an initializer or assignment (variable := 1) would be evaluated only if and when execution reaches it. In this case, it is reassigned every time the function is called.

If you declare a global variable only inside each (and every) function which must use it and never outside, it will not be visible (and therefore will not be accidentally used) in any other function.

Re: Can't create global variables inside function per documentation

Posted: 16 Jan 2017, 02:52
by pneumatic
Thank you. In that case I will use the "assume-global mode" declaration before messagebox in function 2.

I still find it unintuitive though how superglobals are automatically assigned when there is no local variable of that name, but regular globals are not. This is what confused me, because the former lead me to believe there was a rule going on behind the scenes of "if no local/static variable, then look for a global" as is the case with superglobals. But alas, regular globals do not seem to share that rule.

Re: Can't create global variables inside function per documentation  Topic is solved

Posted: 16 Jan 2017, 03:35
by lexikos
pneumatic wrote:I still find it unintuitive though how superglobals are automatically assigned when there is no local variable of that name, but regular globals are not.
I suppose you mean "accessible". They are not automatically "assigned".

That's the entire purpose of "super-global" variables and the only thing that sets them apart from normal globals.

Originally there were only global variables. When functions were added, they were designed to be local by default and require an explicit declaration inside the function to opt-in to accessing any global variable. I suppose the benefit was that once you understand the rules, you could see at a glance which variables are local and which are global, because all relevant declarations are right there in the function. There's also less risk of unknowingly introducing conflicts when you add global variables elsewhere, because assume-local functions are unaffected.

(Personally, I think that requiring each function to opt-in contradicts the very idea of a global variable, but it's only the terminology I object to, not the behaviour, and I haven't come up with any better terms.)

I added "super-globals" for convenience (so that if you have numerous functions using one global variable, you only need one declaration), and because they more closely match how I expected global variables to work.


If the declaration is inside a function, it makes sense for the declaration to only affect that function.

If the declaration is not inside a function, it makes sense for the declaration to affect either a) any code not inside a function or b) every code, at least by default. 'a' wouldn't be useful because it would mean that the global keyword has no effect at all outside a function.