LoWang Posted September 15, 2010 Share Posted September 15, 2010 Hello, I have a file with functions which I usually include to my scripts. I found out that I have to be carefull about variables used in the functions because they can overwrite global variables with the same name used in the host script, so I now declare them "local" in the first line of the defined function. Is this as it should be? Also those functions sometimes use global variables which may not be declared always, so I add "global $var" to ensure it is there at least empty to avoid script error. I think it should work, but just tell me if my logic is OK or I miss something. Thanks Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted September 15, 2010 Moderators Share Posted September 15, 2010 LoWang,When you write UDFs to be used as #include files (which is basically what you are doing here) you have to take great care to avoid the very problems that you mention. A couple of tips:- Use as few Global variables in the functions as possible. If you must use Global variables, make sure they have a suitably unique name - I usually use something like _UDFName_FunctionName - to reduce the risk of them getting overwritten by other parts of the script.- Declare all other variables within the function as Local as you are doing - AutoIt does this automatically, but it is better practice to make it explicit.You might also find the Variables - using Global, Local and ByRef tutorial in the Wiki an interesting read. 5M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
water Posted September 15, 2010 Share Posted September 15, 2010 Local variables are fine as long as you don't want to access them outside the function (main script or another function). If you have to define global variables in your function I would suggest to use a prefix so you don't overwrite an already existing global variable by accident. My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
LoWang Posted September 15, 2010 Author Share Posted September 15, 2010 (edited) - Declare all other variables within the function as Local as you are doing - AutoIt does this automatically, but it is better practice to make it explicit.How do you mean it? If I have a script which has something like $a=1 in the main body and then I use an included function which uses $a variable in a for cycle for example. Then this variable is overwritten in the main script! And that's why I should use "local" in the func to avoid this. So what do you mean by Autoit doing it automatically? Edited September 15, 2010 by LoWang Link to comment Share on other sites More sharing options...
water Posted September 15, 2010 Share Posted September 15, 2010 (edited) "automatically" means that AutoIt defines the variable on first access if not already defined. $a = 1let's AutoIt define the variable $a and assing the value. Edited September 15, 2010 by water My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted September 15, 2010 Moderators Share Posted September 15, 2010 LoWang, If I have a script which has something like $a=1 in the main body and then I use an included function which uses $a variable in a for cycle for example. Then this variable is overwritten in the main script!No, this will not happen - even if you do not specify the scope of the variables. As you can see here. For $a = 1 To 3 ConsoleWrite("$a before function = " & $a & @CRLF) _Func() ConsoleWrite("$a after function = " & $a & @CRLF) Next Func _Func() For $a = 1 To 3 ConsoleWrite("$a in function = " & $a & @CRLF) Next EndFunc The result: $a before function = 1 $a in function = 1 $a in function = 2 $a in function = 3 $a after function = 1 $a before function = 2 $a in function = 1 $a in function = 2 $a in function = 3 $a after function = 2 $a before function = 3 $a in function = 1 $a in function = 2 $a in function = 3 $a after function = 3 Did you read the Wiki tutorial I linked to? All of these questions are answered in there, so please do read it. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
MHz Posted September 15, 2010 Share Posted September 15, 2010 Melba23, AutoIt3 does an implicit local declaration on the counter variable on the For loop. Your example only shows that Local effect with using a For loop. It is not consistent variable behavior to use as an example. It displays the rather unusual aspect of the For loop. This example shows the natural behavior of a variable which has a dimmed scope by default. $a = 1 ConsoleWrite("$a before function = " & $a & @CRLF) _Func() ConsoleWrite("$a after function = " & $a & @CRLF) Func _Func() $a = 2 EndFunc The $a variable is global since first assignment is dimmed in a global section of the script. The function call sees $a is dimmed and since $a is already set in global scope, then $a in the function is treated as the same global $a. So, $a changes from 1 to 2. I hope my correction does not offend you as it is nothing personal. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted September 15, 2010 Moderators Share Posted September 15, 2010 MHz,You are quite correct - and I am not offended in the least. This is why I always recommend using explicit Global/Local declarations for all variables - and using descriptive names for them! M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
MHz Posted September 15, 2010 Share Posted September 15, 2010 LoWang,...so I now declare them "local" in the first line of the defined function. Is this as it should be?Should is not the correct way to look at this IMO. It is rather ideal if variables outside functions are all global and all variables inside functions are local. There may be minor times when when a dimmed variable in a function is suitable. You have made the right choice by using Local on those function variables that you want to keep local. Adding to the 1st line is what I do as you can do a quick review of the local variables without needing to search through all the function code to see what is declared local which of course is just a preference decision.Also those functions sometimes use global variables which may not be declared always, so I add "global $var" to ensure it is there at least empty to avoid script error. I think it should work, but just tell me if my logic is OK or I miss something. ThanksMost functions I expect to only have local variables. If not, then review if you could have done the functions different as to make those function variables more local if possible. It may even mean the functions or a entire script rewrite is needed if the variables are not handled well with scope i.e a design issue of the script. Using the keyword Global in a function is considered not good and needs consideration on how if possible to avoid doing that. 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