I just discovered that if I try to use a global variable inside a function that is declared after a simple hotkey, a warning appears saying that this global variable doesn't has a value.
Illustration:
In this example, when I press Shift + l the warning appears.
Can anyone explain ?
Variables have to be declared in the auto-execute section or within a hotkey/hotstring/or another function.
#Warn
global a := "10/10" ; super-global variable
$+p:: Pause
$+1:: foo()
foo(){
MsgBox % "a = " . a
}
or
to access global variables within a function you need to add global within the function:
#Warn
a := "10/10" ; global variable
$+p:: Pause
$+1:: foo()
foo(){
global
MsgBox % "a = " . a
}
or:
#Warn
$+1::
global a := "10/10"
foo()
return
$+p:: Pause
foo(){
MsgBox % "a = " . a
}
For more details read Local and Global Variables
Related
var1 := "this works"
#If WinActive("")
d::d
#If
var2 := "this doesn't"
x::
MsgBox, %var1%, %var2%
return
When the hotkey is triggered, it only displays var1, acting like var2 doesn't exist at all.
Why does this happen and what can I do to access var2 from the hotkey?
I can't move var2 up, since my actual code is split accross two files.
You cannot define a variable between or after hotkeys or hotstrings.
Hotkeys/Hotstrings terminate the automatic execution of code lines and the line
var2 := "this doesn't"
never becomes true because is never executed.
A variable has to be defined
in the auto-execute section (top of the script before the first return or hotkey),
or in a hotkey/hotstring,
or in a label (subroutine),
or in a function.
I'm having a problem with accessing the %1% ( Startup Param that has been passed to the Script by the console ) in Autohotkey.
When I use the following code (outside of a function):
Msgbox %1%
I get the output of the Param that has been passed to the Script. But as soon as I use the following Code:
HelloWorld() {
Msgbox %1%
}
HelloWorld()
The output is empty.
I also tried to assign %1% to a global variable, or to pass it to the Function as a parameter but it didn't work for me neither.
Thank you
I believe the command line parameter variables are considered global variables, so in order to use them in a non-expression context inside a function you have to declare them as global:
HelloWorld() {
global 1
Msgbox %1%
}
HelloWorld()
It gets even more confusing once you want to use them in expressions (such as using % in the text argument for MsgBox), since they will be treated as numbers so you have to indirectly access them through variables:
HelloWorld() {
;global 1
; Neither of these two expressions access the variable named "1"
;Msgbox % 1
;Msgbox % %1%
; You have to do this instead:
p := 1
MsgBox % %p% ; p is translated to 1 and then "1" is used as a variable name
}
HelloWorld()
Note that doing this doesn't require global 1.
If you're using the newest version of AHK, you instead probably want to use the newly introduced built-in variable A_Args, which is an array that holds the command line parameters. Being built-in, it doesn't have to be declared global, and it ultimately makes the code clearer:
HelloWorld() {
MsgBox % "Number of command line args received: " A_Args.Length() "`n"
. "First argument: " A_Args[1]
}
HelloWorld()
Just declare your cli variables as Global - outside the function - to make them globally available to any and all internal functions. For me, this is how I do it with my version of AHK (Version 1.1.25.01):
Global 1, 2, 3
HelloWorld() {
MsgBox Hello`t1:`t%1%`n`t2:`t%2%`n`t3:`t%3%
}
HelloWorld()
Note, these are different command lines:
"Scripts\myScript.ahk" one two three
"Scripts\myScript.ahk" "one two" three
"Scripts\myScript.ahk" "one" "two three"
"Scripts\myScript.ahk" "one two three"
The first is three separate parameters, the second and third, only two and the last is only one param (2 and 3 exist, but are empty).
Hth,
I made global a variable in main m.file and used that variable in a function m.file and I had no problem. But, I wanna make global a variable in function m.file and use that variable in main m.file.
For this aim, I wrote:
function cost=MY_Fun(X)
global m
.
.
end
in function m.file, and wrote "global m" in main m.file. But, I get m=[]! How can I do that, so that the main m.file could correctly find the "m" value?
In the main script, if you are using m before the function call to MY_Fun, it would be empty. But after it, would have the value assigned inside MY_Fun. m would get the value from MY_Fun, only after the function gets called from the main script. The following codes might help you understand.
Main Script
global m
m_before_fun = m
cost1=MY_Fun(1);
m_after_fun = m
Function
function cost=MY_Fun(X)
%%// Declare m as a global variable
global m
%%// Assign some value to m
m = 10;
cost = 1;
return; %%// I prefer RETURN to END
Output
m_before_fun =
[]
m_after_fun =
10
supposedlyGlobalVariable := "blah"
ARoutine()
{
localVariable := "asdf"
MsgBox, The global variable value is %supposedlyGlobalVariable%. The local variable value is %localVariable%.
}
^!X:: ;This assigns the hotkey CTRL + ALT + X to run the routine
ARoutine()
return
Run the code and the result is:
"The global variable value is . The local variable value is asdf."
The documentation states:
Variable scope and declarations: With the exception of local variables
in functions, all variables are global; that is, their contents may be
read or altered by any part of the script.
Why does my global variable not have scope within the function?
The documentation for global variables can be found here:
https://autohotkey.com/docs/Functions.htm#Global
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. For
example:
LogToFile(TextToLog)
{
global LogFileName
FileAppend, %TextToLog%`n, %LogFileName%
}
I believe the concept of global, with AHK, is a bit different than in other languages. With AHK you can create a variable and use it within multiple hotkeys, and subroutines, without declaring it as global.
Gv := 0
f1::SetTimer, Action, % (on:=!on) ? (1000) : ("Off")
Action:
Gv++
trayTip,, % Gv
Return
f2::Msgbox, % Gv
Explaination of code:
The F1 key toggles a timer to run the subroutine: Action every 1000ms.
% starts an expression.
on:=!on reverses the binary value of variable on every time F1 is pressed.
?: together is called the ternary operator.
When on=1 delay is set to 1000ms; when on=0 the timer is turned Off.
The ++ operator adds 1 to variable Gv.
This makes things easier:
https://www.autohotkey.com/docs/Functions.htm#SuperGlobal
Super-global variables [v1.1.05+]: If a global declaration appears
outside of any function, it takes effect for all functions by default
(excluding force-local functions). This avoids the need to redeclare
the variable in each function. However, if a function parameter or
local variable with the same name is declared, it takes precedence
over the global variable. Variables created by the class keyword are
also super-global.
Just declare your variable as global in the main script:
global supposedlyGlobalVariable := "blah"
P.Brian, It works when you do this.. I know it doesn't explain why, but this might be your workaround.
#Persistent
GlobalVariable = "blah"
RETURN
ARoutine:
{
localVariable := "asdf"
MsgBox, The global variable value is %GlobalVariable%. The local variable value is %localVariable%.
}
Return
^!X:: ;This assigns the hotkey CTRL + ALT + X to run the routine
gosub, ARoutine
return
You just need to declare the variable as global inside your function
supposedlyGlobalVariable := "blah"
ARoutine()
{
global supposedlyGlobalVariable
localVariable := "asdf"
MsgBox, The global variable value is %supposedlyGlobalVariable%. The local variable
value is %localVariable%.
}
^!X:: ;This assigns the hotkey CTRL + ALT + X to run the routine
ARoutine()
return
Is it possible to declare global variables in MATLAB inside a loop:
cellvar = { 'ni' ; 'equity' ; 'assets' } ;
for i = 1:size(cellvar,1)
global cellvar{1} % --> THIS GIVES AN ERROR
end
% Desired result:
global ni
global equity
global assets
Matlab documentation says: "There is no function form of the global command (i.e., you cannot use parentheses and quote the variable names)." Any suggested work-around? Thanks!
You can use the EVAL function to do this:
for var = 1:numel(cellvar)
eval(['global ' cellvar{var}]);
end
Also, since GLOBAL accepts a command-line list of variable names, you could avoid the for loop by using SPRINTF to concatenate your variable names into one string to be evaluated:
eval(['global' sprintf(' %s',cellvar{:})]);