ALarvi019 Posted March 19, 2023 Share Posted March 19, 2023 Hello everyone, It helped me a lot with all the messages in the forum, the truth is that it is a community that has many resources and I have never had to ask a question until now since I cannot find any answer on the web. the question is that i need to declare global dynamic variables inside a function I leave you my example code: Func InitialSetupFile() $SetupFile = ReadSetupFile() ;~ Declare all global variables from config File Local $oJson = Json_Decode($JSON_setup) Local $SETOPJSON = Json_Get($oJson, '.setup') For $i = 0 To UBound($SETOPJSON) - 1 Step 1 Local $SETOPJSON2 = Json_Get($oJson, '.setup[' & $i & '].values') For $j = 0 To UBound($SETOPJSON2) - 1 Step 1 Local $iniGroup = Json_Get($oJson, '.setup[' & $i & '].values[' & $j & '].iniGroup') Local $iniProp = Json_Get($oJson, '.setup[' & $i & '].values[' & $j & '].iniProp') Local $defaultValue = Json_Get($oJson, '.setup[' & $i & '].values[' & $j & '].defaultValue') $dynamicVariableName = "Setup_" & $iniGroup & "_" & $iniProp Global $dynamicVariableName Assign($dynamicVariableName, $SetupFile[$i][$j][3]) Next Next EndFunc InitialSetupFile() I will explain the code 1. read a file with values and return them in an array inside $SetupFile 2. I loop through a variable in json format ($JSON_setup) to extract the values I need to create my global variables 3. use the extracted values to create global variable $$dynamicVariableName and assign the extracted value from the configuration file *** The thing is that if I run this code in the root of the script, that is, I run it outside the InitialSetupFile() function, everything works as I expect, but if I run it inside the function, I can't access any global dynamic variable later. Does anyone know what may be going on and can provide me with a solution to make this work? Thank you very much (By google translator) Link to comment Share on other sites More sharing options...
Developers Jos Posted March 19, 2023 Developers Share Posted March 19, 2023 Moved to the appropriate AutoIt General Help and Support forum, as the Developer General Discussion forum very clearly states: Quote General development and scripting discussions. Do not create AutoIt-related topics here, use the AutoIt General Help and Support or AutoIt Technical Discussion forums. Moderation Team SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
mistersquirrle Posted March 19, 2023 Share Posted March 19, 2023 First, it's best if you understand how scope works, so I recommend that you read this page: https://www.autoitscript.com/wiki/Variables_-_using_Global,_Local,_Static_and_ByRef Second, since AutoIt parses/executes line by line, if you try to access your $dynamicVariableName before the function has run, it does NOT exist. Instead, you should do something like this: ; Declare variables first/at the top of your script. This way they're initialized and you won't try to access them before they exist Global $dynamicVariableName InitialSetupFile() ; Generally in AutoIt functions are put at the bottom of the script. Functions are loaded when the script starts, so they don't need to appear before they're used Func InitialSetupFile() ; Declare your variables first ; It's not a good idea to do delcaration (Local) inside of loops, since you're re-creating the variable each loop Local $defaultValue Local $iniGroup, $iniProp Local $SETOPJSON, $SETOPJSON2 Local $SetupFile = ReadSetupFile() ; You should always declare new variables with the correct scope ;~ Declare all global variables from config File Local $oJson = Json_Decode($JSON_setup) $SETOPJSON = Json_Get($oJson, '.setup') For $i = 0 To UBound($SETOPJSON) - 1 Step 1 $SETOPJSON2 = Json_Get($oJson, '.setup[' & $i & '].values') For $j = 0 To UBound($SETOPJSON2) - 1 Step 1 $iniGroup = Json_Get($oJson, '.setup[' & $i & '].values[' & $j & '].iniGroup') $iniProp = Json_Get($oJson, '.setup[' & $i & '].values[' & $j & '].iniProp') $defaultValue = Json_Get($oJson, '.setup[' & $i & '].values[' & $j & '].defaultValue') $dynamicVariableName = $SetupFile[$i][$j][3] ; Update the Global variable. Since it's global, it is accessible here ; I'm not sure what value you want for $dynamicVariableName, either ("Setup_" & $iniGroup & "_" & $iniProp) or ($SetupFile[$i][$j][3]) ;$dynamicVariableName = "Setup_" & $iniGroup & "_" & $iniProp ;Global $dynamicVariableName ;Assign($dynamicVariableName, $SetupFile[$i][$j][3]) Next Next EndFunc ;==>InitialSetupFile Variables that are not inside functions are in the Global scope, and are accessible inside of functions. However if you declare a Global variable in a function, that variable does NOT exist until that function runs. Also note that you can use a Local variable by the same name as a Global variable in a function, and while in the function you'll use the Local version (however it does NOT inherit or use the global scopes value, unless you set it to that). We ought not to misbehave, but we should look as though we could. Link to comment Share on other sites More sharing options...
ALarvi019 Posted March 19, 2023 Author Share Posted March 19, 2023 Thanks for the reply @mistersquirrle I already read the link https://www.autoitscript.com/wiki/Variables_-_using_Global,_Local,_Static_and_ByRef TI'll try your proposal tomorrow, but logic tells me that when I put at the top of my script this: Global $dynamicVariableName I'm actually globally declaring the variable $dynamicVariableName, Not the dynamic variable I want to create: "Setup_" & $iniGroup & "_" & $iniProp (example: $Setup_Main_Path) I am right? Link to comment Share on other sites More sharing options...
mistersquirrle Posted March 19, 2023 Share Posted March 19, 2023 (edited) I think I see now what you're looking to do, you're trying to create a new variable with a dynamic name that's stored in $dynamicVariableName and is: "Setup_" & $iniGroup & "_" & $iniProp. So you're trying to dynamically create the variable $Setup_Main_Path, and you may not know what name you want when you create the script. Honestly this is not something that I do, I usually know what variables I want beforehand. But let me ask this, then, once you've created the global variable $Setup_Main_Path, then what? How are you going to access it, if you don't know the name? With Eval each time? Eval($dynamicVariableName). My question then is... why? Why not just create a variable (array or map maybe) to hold the data that you know the name of? I would recommend checking out Maps in the latest version of AutoIt. They have been added to the stable release: https://www.autoitscript.com/autoit3/docs/intro/lang_variables.htm#ArrayMaps This way, you can instead do something like this: ; Declare variables first/at the top of your script. This way they're initialized and you won't try to access them before they exist Global $mDynamicVars[] ; [] - create a Map when you don't set a size or any values (otherwise it will create an array) InitialSetupFile() ConsoleWrite($mDynamicVars["Setup_Main_Path"] & @CRLF) ; Generally in AutoIt functions are put at the bottom of the script. Functions are loaded when the script starts, so they don't need to appear before they're used Func InitialSetupFile() ; Declare your variables first ; It's not a good idea to do delcaration (Local) inside of loops, since you're re-creating the variable each loop Local $defaultValue Local $iniGroup, $iniProp Local $SETOPJSON, $SETOPJSON2 Local $SetupFile = ReadSetupFile() ; You should always declare new variables with the correct scope ;~ Declare all global variables from config File Local $oJson = Json_Decode($JSON_setup) $SETOPJSON = Json_Get($oJson, '.setup') For $i = 0 To UBound($SETOPJSON) - 1 Step 1 $SETOPJSON2 = Json_Get($oJson, '.setup[' & $i & '].values') For $j = 0 To UBound($SETOPJSON2) - 1 Step 1 $iniGroup = Json_Get($oJson, '.setup[' & $i & '].values[' & $j & '].iniGroup') $iniProp = Json_Get($oJson, '.setup[' & $i & '].values[' & $j & '].iniProp') $defaultValue = Json_Get($oJson, '.setup[' & $i & '].values[' & $j & '].defaultValue') ; Create a new map key $mDynamicVars["Setup_" & $iniGroup & "_" & $iniProp] = $SetupFile[$i][$j][3] Next Next EndFunc ;==>InitialSetupFile Edited March 19, 2023 by mistersquirrle SOLVE-SMART 1 We ought not to misbehave, but we should look as though we could. Link to comment Share on other sites More sharing options...
Solution TheXman Posted March 19, 2023 Solution Share Posted March 19, 2023 1 hour ago, ALarvi019 said: the question is that i need to declare global dynamic variables inside a function If you must, you can do it using the Assign() function and you can read the dynamically created global variable with the Eval() function. Example: #include <Constants.au3> Const $IniGroup = "Main", _ $IniProp = "Path" example() ConsoleWrite("Setup_" & $IniGroup & "_" & $IniProp & " = " & Eval("Setup_" & $IniGroup & "_" & $IniProp) & @CRLF) Func example() ;Create and assign a value to a dynamically created variable name Assign("Setup_" & $IniGroup & "_" & $IniProp, "Some Value", $ASSIGN_FORCEGLOBAL) EndFunc Console: Setup_Main_Path = Some Value mistersquirrle 1 CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
ALarvi019 Posted March 19, 2023 Author Share Posted March 19, 2023 31 minutes ago, mistersquirrle said: I think I see now what you're looking to do, you're trying to create a new variable with a dynamic name that's stored in $dynamicVariableName and is: "Setup_" & $iniGroup & "_" & $iniProp. So you're trying to dynamically create the variable $Setup_Main_Path, and you may not know what name you want when you create the script. Honestly this is not something that I do, I usually know what variables I want beforehand. But let me ask this, then, once you've created the global variable $Setup_Main_Path, then what? How are you going to access it, if you don't know the name? With Eval each time? Eval($dynamicVariableName). My question then is... why? Why not just create a variable (array or map maybe) to hold the data that you know the name of? I would recommend checking out Maps in the latest version of AutoIt. They have been added to the stable release: https://www.autoitscript.com/autoit3/docs/intro/lang_variables.htm#ArrayMaps This way, you can instead do something like this: ; Declare variables first/at the top of your script. This way they're initialized and you won't try to access them before they exist Global $mDynamicVars[] ; [] - create a Map when you don't set a size or any values (otherwise it will create an array) InitialSetupFile() ConsoleWrite($mDynamicVars["Setup_Main_Path"] & @CRLF) ; Generally in AutoIt functions are put at the bottom of the script. Functions are loaded when the script starts, so they don't need to appear before they're used Func InitialSetupFile() ; Declare your variables first ; It's not a good idea to do delcaration (Local) inside of loops, since you're re-creating the variable each loop Local $defaultValue Local $iniGroup, $iniProp Local $SETOPJSON, $SETOPJSON2 Local $SetupFile = ReadSetupFile() ; You should always declare new variables with the correct scope ;~ Declare all global variables from config File Local $oJson = Json_Decode($JSON_setup) $SETOPJSON = Json_Get($oJson, '.setup') For $i = 0 To UBound($SETOPJSON) - 1 Step 1 $SETOPJSON2 = Json_Get($oJson, '.setup[' & $i & '].values') For $j = 0 To UBound($SETOPJSON2) - 1 Step 1 $iniGroup = Json_Get($oJson, '.setup[' & $i & '].values[' & $j & '].iniGroup') $iniProp = Json_Get($oJson, '.setup[' & $i & '].values[' & $j & '].iniProp') $defaultValue = Json_Get($oJson, '.setup[' & $i & '].values[' & $j & '].defaultValue') ; Create a new map key $mDynamicVars["Setup_" & $iniGroup & "_" & $iniProp] = $SetupFile[$i][$j][3] Next Next EndFunc ;==>InitialSetupFile I like this idea!!! How can I access the value? MsgBox...... $mDynamicVars["Setup_Main_Path"] thanks Link to comment Share on other sites More sharing options...
mistersquirrle Posted March 20, 2023 Share Posted March 20, 2023 What do you mean how can you access it? You just did, basically. I also have it being used in ConsoleWrite in the example. It's accessed like: MsgBox(0, 'Setup_Main_Path', $mDynamicVars["Setup_Main_Path"]) Or, you can do this to get all of the keys and values for that key: Global $mDynamicVars[] $mDynamicVars["Setup_Main_Path"] = 'Setup_Main_Path' $mDynamicVars["Meow"] = 'Cat' $mDynamicVars["Woof"] = 'Dog' Global $aKeys = MapKeys($mDynamicVars) For $sKey In $aKeys ConsoleWrite($sKey & ': ' & $mDynamicVars[$sKey] & @CRLF) Next We ought not to misbehave, but we should look as though we could. Link to comment Share on other sites More sharing options...
ALarvi019 Posted March 20, 2023 Author Share Posted March 20, 2023 hello all @mistersquirrle Although your idea of using maps is very cool and interesting, I would have to change many parts of my code to make it work. Thank you very much for your help and time. @TheXman Thank you very much for the answer, your solution is perfect for me. $ASSIGN_FORCEGLOBAL Assign("Setup_" & $IniGroup & "_" & $IniProp, "Some Value", $ASSIGN_FORCEGLOBAL) I can access dynamic variables outside of functions just fine. It was what I needed!!! Problem solved!! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now