Best coding practices: Difference between revisions
No edit summary |
m (Fixed a few typos) |
||
Line 1: | Line 1: | ||
Outlined in this section is a detailed explanation of what are to be considered the best coding practices within AutoIt. These recommendations are based on accepted coding practices common to a number of other programming languages. You do not need to follow them, but it is recommended that you do. | Outlined in this section is a detailed explanation of what are to be considered the best coding practices within AutoIt. These recommendations are based on accepted coding practices common to a number of other programming languages. You do not need to follow them, but it is recommended that you do. | ||
A few notes: | A few notes: | ||
* You must use the latest version of AutoIt (v3.3.10.0 or above) to run the examples below. | * You must use the latest version of AutoIt (v3.3.10.0 or above) to run the examples below. | ||
__TOC__ | __TOC__ | ||
Line 51: | Line 49: | ||
| k || Keywords || $kKeyword = Default | | k || Keywords || $kKeyword = Default | ||
|} | |} | ||
Variables are named following this schema: | Variables are named following this schema: | ||
Line 86: | Line 83: | ||
Local $sString = False | Local $sString = False | ||
; | ; Correct initialization | ||
Local $iInteger = 0 | Local $iInteger = 0 | ||
Local $sString = '' | Local $sString = '' | ||
Line 96: | Line 93: | ||
Example: | Example: | ||
<syntaxhighlight lang="autoit"> | <syntaxhighlight lang="autoit"> | ||
; | ; Not recommended | ||
Local $sString = "", $iInteger = 0, $asArray = ["a","b","c"] ; Mixed data types | Local $sString = "", $iInteger = 0, $asArray = ["a","b","c"] ; Mixed data types | ||
; | ; Recommended | ||
Local $iLeft = 10, $iTop = 10 ; integers | Local $iLeft = 10, $iTop = 10 ; integers | ||
Local $idGo = GUICtrlCreateButton("Go", $iLeft, $iTop), $idQuit = GUICtrlCreateButton("Quit", 50, 10) ; controlIDs | Local $idGo = GUICtrlCreateButton("Go", $iLeft, $iTop), $idQuit = GUICtrlCreateButton("Quit", 50, 10) ; controlIDs | ||
Line 117: | Line 114: | ||
|} | |} | ||
With this method, you will avoid non wanted re-assignments. | With this method, you will avoid non wanted re-assignments. | ||
Example: | Example: | ||
Line 147: | Line 143: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
* A variable declared globally (with the Global keyword) is visible anywhere in the script.<br />Always declare your global variables in the global scope, not in the functions. It will prevent another function to use it before its declaration and the declaration is implicit (see [[#jumpsec1|examples]]). | |||
* A variable declared globally (with the Global keyword) is visible anywhere in the script. | |||
Always declare your global variables in the global scope, not in the functions. It will prevent another function to use it before its declaration and the declaration is implicit (see [[#jumpsec1|examples]]). | |||
* A variable declared locally (with the Local keyword), has a visibility which depends of the scope where it's declared. | * A variable declared locally (with the Local keyword), has a visibility which depends of the scope where it's declared. | ||
:Declaration in the global scope: the variable is nonetheless visible everywhere; declare it as Local if this one is only used in the same scope. | :Declaration in the global scope: the variable is nonetheless visible everywhere; declare it as Local if this one is only used in the same scope. | ||
:Declaration in a function: the variable is visible by the function itself and nowhere else. | :Declaration in a function: the variable is visible by the function itself and nowhere else. | ||
Structure of a code scope: | Structure of a code scope: | ||
Line 197: | Line 190: | ||
EndFunc ;==>MyFunc | EndFunc ;==>MyFunc | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Concerning the Dim keyword, its recommended usage is limited to empty an existing array (Example 1) or to redeclare a function parameter (Example 2). | Concerning the Dim keyword, its recommended usage is limited to empty an existing array (Example 1) or to redeclare a function parameter (Example 2). | ||
Line 243: | Line 235: | ||
EndFunc ;==>MyFunc | EndFunc ;==>MyFunc | ||
</syntaxhighlight> | </syntaxhighlight> | ||
And for the ReDim keyword, limit its use to resize an array you want to keep its content: | And for the ReDim keyword, limit its use to resize an array you want to keep its content: | ||
Line 263: | Line 254: | ||
_ArrayDisplay($aArray) | _ArrayDisplay($aArray) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Why using Dim over Local/Global is not always a good option: | Why using Dim over Local/Global is not always a good option: | ||
Line 296: | Line 286: | ||
EndFunc ;==>SomeFunc | EndFunc ;==>SomeFunc | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<span id="jumpsec1">Declaring Global variables in a Function is never a good idea:</span> | <span id="jumpsec1">Declaring Global variables in a Function is never a good idea:</span> | ||
Line 335: | Line 324: | ||
EndFunc ;==>SomeFunc | EndFunc ;==>SomeFunc | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Declaring variables in loops (For, While, Do etc..) can have an affect on efficiency: | Declaring variables in loops (For, While, Do etc..) can have an affect on efficiency: | ||
Line 358: | Line 346: | ||
MsgBox($MB_SYSTEMMODAL, '', $iInt) ; This will display 10. | MsgBox($MB_SYSTEMMODAL, '', $iInt) ; This will display 10. | ||
</syntaxhighlight> | </syntaxhighlight> | ||
There is no requirement to declare the iteration count variable in a loop: | There is no requirement to declare the iteration count variable in a loop: | ||
Line 386: | Line 373: | ||
The Const keyword may be used in a first by some of you to avoid re-assignments. | The Const keyword may be used in a first by some of you to avoid re-assignments. | ||
The best way to use them is not this last case, the constants should be used for real static variables, meaning that their value won't change regardless to the instance of the program. | The best way to use them is not this last case, the constants should be used for real static variables, meaning that their value won't change regardless to the instance of the program. | ||
Example: | Example: | ||
<syntaxhighlight lang="autoit"> | <syntaxhighlight lang="autoit"> | ||
; | ; Not recommended | ||
Local Const $hGUI = GUICreate("MyGUI") | Local Const $hGUI = GUICreate("MyGUI") | ||
; The handle of the window is unique, it's generated by Windows and changes. | ; The handle of the window is unique, it's generated by Windows and changes. | ||
; | ; Recommended | ||
Local Const $iMyAge = 19 | Local Const $iMyAge = 19 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Static === | === Static === | ||
Line 422: | Line 407: | ||
EndFunc ;==>SomeFunc | EndFunc ;==>SomeFunc | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Enum === | === Enum === | ||
Line 460: | Line 444: | ||
EndFunc ;==>Example | EndFunc ;==>Example | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Au3Check directive == | == Au3Check directive == | ||
Line 471: | Line 452: | ||
#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7 | #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Magic Numbers == | == Magic Numbers == | ||
Line 553: | Line 531: | ||
Those includes may be included in more than one script of your project because they are needed for some includes or your script itself. | Those includes may be included in more than one script of your project because they are needed for some includes or your script itself. | ||
In that case, the code will be duplicated which is not a good thing especially if you have (and it's mainly the case) constants declared in those files, in so far as the constants cannot be redeclared/reassigned; same thing for functions. | In that case, the code will be duplicated which is not a good thing especially if you have (and it's mainly the case) constants declared in those files, in so far as the constants cannot be redeclared/reassigned; same thing for functions. | ||
Put the directive in top of your UDF (library) to avoid itself to be included more than once : | Put the directive in top of your UDF (library) to avoid itself to be included more than once : |
Revision as of 09:08, 8 March 2015
Outlined in this section is a detailed explanation of what are to be considered the best coding practices within AutoIt. These recommendations are based on accepted coding practices common to a number of other programming languages. You do not need to follow them, but it is recommended that you do.
A few notes:
- You must use the latest version of AutoIt (v3.3.10.0 or above) to run the examples below.
Names of Variables
The variable naming convention used in AutoIt is based on Apps Hungarian notation. The prefix defines the logical data type rather than the physical data type: in this way, it gives a hint as to what the variable's purpose is, or what it represents. The prefix does not encode the actual data type: this occurs during assignment. See the table below for accepted standards.
prefix | covering type | example |
---|---|---|
i | Integer | $iInteger = 10 |
f | Floating point | $fFloat = 0.123 |
n | General number (no preference) | $nNumber = 0 |
a | Arrays | $aArray[0] |
m | Maps | $mMap[] |
s | Strings (chars included) | $sString = "hello world" |
b | Booleans | $bBool = True |
d | Binaries | $dBinary = Binary("0x80000000") |
id | An AutoIt controlID | $idButton = GUICtrlCreateButton("OK", 5, 5) |
h | Handles (and GUI handles) | $hGUI = GUICreate("My GUI") |
fu | Functions | $fuMessage = MsgBox |
p | Pointers | $pRect = DllStructGetPtr($tRECT) |
tag | Structures definition | $tagDATE = "struct; word Year;word Month;word Dow;word Day; endstruct" |
t | Structures | $t = 0 |
o | Objects | $oShell = ObjCreate("shell.application") |
v | Variant | $vData = ClipGet() |
e | Enumerations | Enum $e1st = 1, $e2nd, $e3rd |
k | Keywords | $kKeyword = Default |
Variables are named following this schema:
dollar prefix | type (lower case) | [optional] subtype (lower case) | var name (first letter in upper case) |
---|---|---|---|
$ | a | h | Handles |
Examples:
; Assign a local variable the integer 7.
Local $iWeekDays = 7
; Assign a local variable the value of Pi.
Local $fPi = 3.14159265358979
; Assign a local variable an array of strings.
Local $asArray[7] = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
; Assign a local variable an array of numbers.
Local $anArray[4] = [0, 0.25, 3 / 4, 12]
Variable Initialization
When initializing variables there are several points to consider. It is bad practice to hog memory by holding data which is not immediately required. It is therefore recommended that you declare and initialize variables immediately prior to use. If you wish to assign a default value to a variable which you intend to overwrite later, then the data should be of the same (or the most logical representation of its) type and use as little memory as possible.
Examples:
; Inconsistent data types are considered bad.
Local $iInteger = "0"
Local $sString = False
; Correct initialization
Local $iInteger = 0
Local $sString = ''
To reduce bloat, multiple variables can be declared on a single line. When declaring multiple variables on the same line, it is generally recommended that you stick to declaring one data type on each line. The intention here is to make the code easier to follow, however the best layout will vary according to circumstance.
Example:
; Not recommended
Local $sString = "", $iInteger = 0, $asArray = ["a","b","c"] ; Mixed data types
; Recommended
Local $iLeft = 10, $iTop = 10 ; integers
Local $idGo = GUICtrlCreateButton("Go", $iLeft, $iTop), $idQuit = GUICtrlCreateButton("Quit", 50, 10) ; controlIDs
In some languages it is essential to initialize variables on declaration, but this is not the case with AutoIt. Regarding data type, variables declared without being initialized should be considered as being undefined.
Scopes of Variables
To make the transition, the variables are also named according to their scope.
Global UDF variable | Global variable | Local variable |
---|---|---|
$g__iSomeVar | $g_iSomeVar | $iSomeVar |
With this method, you will avoid non wanted re-assignments.
Example:
#include <MsgBoxConstants.au3>
; Assign a Global variable the number 0.
Global $iSomeVar1 = 0
; Assign a Global variable the number 5.
Global $_iSomeVar2 = 5
SomeFunc()
Func SomeFunc()
; Assign Local variables respectively the numbers 3 and 4.
Local $iSomeVar1 = 3, $iSomeVar2 = 4
; Note: The user inadvertently re-assigned the global variable $iSomeVar1, because this one is not named as "global".
; Display the value of $iSomeVar1.
MsgBox($MB_SYSTEMMODAL, "", "Value of $iSomeVar1: " & $iSomeVar1)
; Display the value of $iSomeVar2.
MsgBox($MB_SYSTEMMODAL, "", "Value of $iSomeVar2: " & $iSomeVar2)
; Display the value of $_iSomeVar2.
MsgBox($MB_SYSTEMMODAL, "", "Value of $_iSomeVar2: " & $_iSomeVar2)
EndFunc
- A variable declared globally (with the Global keyword) is visible anywhere in the script.
Always declare your global variables in the global scope, not in the functions. It will prevent another function to use it before its declaration and the declaration is implicit (see examples).
- A variable declared locally (with the Local keyword), has a visibility which depends of the scope where it's declared.
- Declaration in the global scope: the variable is nonetheless visible everywhere; declare it as Local if this one is only used in the same scope.
- Declaration in a function: the variable is visible by the function itself and nowhere else.
Structure of a code scope:
; Global scope.
; Include the Constants file, it contains various constants; it's needed here for the $MB_SYSTEMMODAL flag of the MsgBox function).
#include <MsgBoxConstants.au3>
; This scope is either Global or Local, depending on where do you use the variables.
; Assign a Global variable the number 0 (which corresponds to an initialization of a variable number), its scope is Global because it's used at least in one function.
Global $_iVar1 = 0
; Assign a Local variable the string "foo", its scope is Local because it's use is restricted to this scope.
Local $_sVar2 = "foo"
; Display the content of $_sVar2
MsgBox($MB_SYSTEMMODAL, "", "Value of $sVar2: " & $_sVar2)
; Re-assign a Local variable the string returned by the function MyFunc.
$_sVar2 = MyFunc()
; Re-Display the content of $_sVar2
MsgBox($MB_SYSTEMMODAL, "", "Value of $sVar2: " & $_sVar2)
; Declare a function (its main utility is described later in Functions, we can see one here which is to create a Local scope).
Func MyFunc()
; Local scope.
; Display the content of $_iVar1.
MsgBox($MB_SYSTEMMODAL, "", "Value of $_iVar1: " & $_iVar1)
; Assign a Local variable the string "bar", its scope is Local because it's use is restricted to the function's scope.
Local $sVar3 = "bar"
; Display the content of $sVar3.
MsgBox($MB_SYSTEMMODAL, "", "Value of $sVar3: " & $sVar3)
; Return the $sVar3 content, it will be visible (if used) to the scope where the function is called.
Return $sVar3
EndFunc ;==>MyFunc
Concerning the Dim keyword, its recommended usage is limited to empty an existing array (Example 1) or to redeclare a function parameter (Example 2).
Example 1:
; Include the Array UDF, it's needed here for the _ArrayDisplay function.
#include <Array.au3>
; Assign a Local variable an array containing numbers with a size of 5.
; Note than an array is based 0 index, to access the first element the code is: $aiArray[0].
Local $aArray[5] = [1, 2, 3, 4, 5]
; Display the contents.
_ArrayDisplay($aArray)
; Empty the array (and keep its size).
Dim $aArray[5]
; Display the contents.
_ArrayDisplay($aArray)
Remark: The variable type of the emptied array is a string, every variable non initialized is a string.
Example 2:
#include <Array.au3>
; Call MyFunc with default parameters ($vParam1 = 0).
MyFunc()
; Assign a Local variable an array containing integers.
Local $aiArray[3] = [3, 4, 5]
; Call MyFunc with $aiArray as parameter ($vParam1 = $aiArray).
MyFunc($aiArray)
Func MyFunc($vParam1 = 0)
; If $vParam1 is NOT an array then redeclare it to an array.
If IsArray($vParam1) = 0 Then
Dim $vParam1[3] = [0, 1, 2]
EndIf
; Display the array.
_ArrayDisplay($vParam1)
EndFunc ;==>MyFunc
And for the ReDim keyword, limit its use to resize an array you want to keep its content:
; Include the Array UDF, it's needed here for the _ArrayDisplay function.
#include <Array.au3>
; Assign a Local variable an array containing numbers with a size of 5.
; Note than an array is based 0 index, to access the first element the code is: $aiArray[0].
Local $aArray[5] = [1, 2, 3, 4, 5]
; Display the contents.
_ArrayDisplay($aArray)
; Resize the array (and keep its content).
ReDim $aArray[3]
; Display the contents.
_ArrayDisplay($aArray)
Why using Dim over Local/Global is not always a good option:
#include <MsgBoxConstants.au3>
Dim $vVariableThatIsGlobal = "This is a variable that has ""Program Scope"" aka Global."
MsgBox($MB_SYSTEMMODAL, "", "An example of why Dim can cause more problems than solve them.")
Example()
Func Example()
MsgBox($MB_SYSTEMMODAL, "", $vVariableThatIsGlobal) ; That looks alright to me as it displays the following text: This is a variable that has "Program Scope" aka Global.
Local $vReturn = SomeFunc() ; Call some random function.
MsgBox($MB_SYSTEMMODAL, $vReturn, $vVariableThatIsGlobal) ; The Global variable ($vVariableThatIsGlobal) changed because I totally forgot I had a duplicate variable name in "SomeFunc".
EndFunc ;==>Example
Func SomeFunc()
; This should create a variable in Local scope if the variable name doesn"t already exist.
; For argument sake I totally forgot that I declared a variable already with the same name.
; Well I only want this to be changed in the function and not the variable at the top of the script.
; Should be OK right? Think again.
Dim $vVariableThatIsGlobal = ""
For $i = 1 To 10
$vVariableThatIsGlobal &= $i ; This will return 12345678910 totally wiping the previous contents of $vVariableThatIsGlobal.
Next
Return $vVariableThatIsGlobal
EndFunc ;==>SomeFunc
Declaring Global variables in a Function is never a good idea:
#include <MsgBoxConstants.au3>
; Calling Example() first will initialise the Global variable $vVariableThatIsGlobal and therefore calling SomeFunc() won't return an error.
; Now look at Example 2.
Example()
Func Example()
; Declaring a variable in a function can cause serious problems, hence why all Global variables should be declared at the top of a script.
Global $vVariableThatIsGlobal = 'This is a variable that has ''File Scope'' aka Global.'
SomeFunc()
EndFunc ;==>Example
Func SomeFunc()
MsgBox($MB_SYSTEMMODAL, '', $vVariableThatIsGlobal) ; As the variable was initialised this will not return an error.
EndFunc ;==>SomeFunc
Example 2:
#include <MsgBoxConstants.au3>
; Calling SomeFunc() first will bypass the Global variable $vVariableThatIsGlobal being initialised and therefore AutoIt has no idea of what data the variable
; $vVariableThatIsGlobal contains.
SomeFunc()
Func Example()
; Declaring a variable in a function can cause serious problems, hence why all Global variables should be declared at the top of a script.
Global $vVariableThatIsGlobal = 'This is a variable that has ''File Scope'' aka Global.'
SomeFunc()
EndFunc ;==>Example
Func SomeFunc()
MsgBox($MB_SYSTEMMODAL, '', $vVariableThatIsGlobal) ; As the variable wasn't initialised this will return an error of "variable used without being declared."
EndFunc ;==>SomeFunc
Declaring variables in loops (For, While, Do etc..) can have an affect on efficiency:
#include <MsgBoxConstants.au3>
; Declaring variables inside loops should be avoided as the variable is re-declared on each repetition.
For $i = 1 To 10 ; $i is in 'loop scope.'
Local $iInt = $i
Next
MsgBox($MB_SYSTEMMODAL, '', $iInt) ; This will display 10.
#include <MsgBoxConstants.au3>
; Declaring variables outside of loops is more efficent in the long run.
Local $iInt = 0
For $i = 1 To 10 ; $i is in 'loop scope.'
$iInt = $i
Next
MsgBox($MB_SYSTEMMODAL, '', $iInt) ; This will display 10.
There is no requirement to declare the iteration count variable in a loop:
; Correct
Local Const $iCount = 99
Local $aArray[$iCount]
For $i = 0 To UBound($iCount) - 1 ; $i is only used in the loop, so there is no requirement to declare it.
$aArray[$i] = $i
Next
; Incorrect
Local Const $iCount = 99
Local $aArray[$iCount]
Local $i ; This is only used to store the iteration count value in the loop and therefore doesn't need to be declared. This is known as loop scope.
For $i = 0 To UBound($iCount) - 1
$aArray[$i] = $i
Next
As you can see, there is the Const keyword in the example, we are going to talk about it.
Const, Static, Enum
Const
We won't talk about the advantages of a constant variable, they are neglibible (for your information, an autoit constant variable is marked as read-only and remains a variable as read-only when compiled).
The Const keyword may be used in a first by some of you to avoid re-assignments. The best way to use them is not this last case, the constants should be used for real static variables, meaning that their value won't change regardless to the instance of the program.
Example:
; Not recommended
Local Const $hGUI = GUICreate("MyGUI")
; The handle of the window is unique, it's generated by Windows and changes.
; Recommended
Local Const $iMyAge = 19
Static
Static variables are the solution to the global variables used in only one function. e.g: Retain variable data once returned from a Function and only use that variable in that particular Function.
Example()
Func Example()
SomeFunc() ; This will display a message box of 1, 1.
SomeFunc() ; This will display a message box of 1, 2.
SomeFunc() ; This will display a message box of 1, 3.
EndFunc ;==>Example
Func SomeFunc()
; This initialises a Static variable in Local scope. When a variable is declared just in Local scope (within a Function,)
; it's destroyed when the Function ends/returns. This isn't the case for a Static variable. The variable can't be
; accessed from anywhere else in the script apart from the Function it was declared in.
Local Static $vVariableThatIsStatic = 0
Local $vVariableThatIsLocal = 0
$vVariableThatIsLocal += 1 ; This will always be 1 as it was destroyed once returned from SomeFunc.
$vVariableThatIsStatic += 1 ; This will increase by 1.
MsgBox(4096, $vVariableThatIsLocal, $vVariableThatIsStatic)
EndFunc ;==>SomeFunc
Enum
This statement is often practical in certain situations:
#include <MsgBoxConstants.au3>
Example()
Func Example()
; Create variables in Local scope and enumerate through the variables. Default is to start from 0.
Local Enum $eCat, $eDog, $eMouse, $eHamster ; $eHamster is equal to the value 3, not 4.
; Create an array in Local scope with 4 elements.
Local $aAnimalNames[4]
; Assign each array element with the name of the respective animal. For example the name of the cat is Jasper.
$aAnimalNames[$eCat] = 'Jasper' ; $eCat is equal to 0, similar to using $aAnimalNames[0]
$aAnimalNames[$eDog] = 'Beethoven' ; $eDog is equal to 1, similar to using $aAnimalNames[1]
$aAnimalNames[$eMouse] = 'Pinky' ; $eMouse is equal to 2, similar to using $aAnimalNames[2]
$aAnimalNames[$eHamster] = 'Fidget' ; $eHamster is equal to 3, similar to using $aAnimalNames[3]
; Display the values of the array.
MsgBox($MB_SYSTEMMODAL, '', '$aAnimalNames[$eCat] = ' & $aAnimalNames[$eCat] & @CRLF & _
'$aAnimalNames[$eDog] = ' & $aAnimalNames[$eDog] & @CRLF & _
'$aAnimalNames[$eMouse] = ' & $aAnimalNames[$eMouse] & @CRLF & _
'$aAnimalNames[$eHamster] = ' & $aAnimalNames[$eHamster] & @CRLF)
; Sometimes using this approach for accessing an element is more practical than using a numerical value, due to the fact changing the index value of
; the enum constant has no affect on it's position in the array. Therefore changing the location of $eCat in the array is as simple as changing the order
; it appears in the initial declaration e.g.
; Local Enum $eDog, $eMouse, $eCat, $eHamster
; Now $eCat is the 2nd element in the array. If you were using numerical values, you would have to manually change all references of $aAnimalNames[0] to
; $aAnimalNames[2], as well as for the other elements which have now shifted.
EndFunc ;==>Example
Au3Check directive
As you may know (and we hope), the Au3Check tool checks your code for syntax errors, variables used without being declared etc. which is a good thing to fix your script.
With the official custom directive used to check the helpfile examples/includes, you can apply the good coding practices listed above:
#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7
Magic Numbers
Magic numbers are arbitrary numbers interspersed throughout a program's source code which do not have an associated identifier. The downside to this is not being able to derive a meaning from the number.
For example:
MsgBox(262144, "Magic Numbers", "It's Adventure Time!")
In this example, the magic number is 262144 with the identifier being $MB_TOPMOST according to the helpfile.
The corrected example:
MsgBox($MB_TOPMOST, "Magic Numbers", "It's Adventure Time!")
Example 2:
; Imagine you're a new user to AutoIt and you come across this code, where would you find -3, -4 or -5 in the help file?
; Since AutoIt is relatively a new concept to you, your first thought isn't to search through all the include files, I mean
; why would you, the help file is there for a reason.
Example()
Func Example()
Local $hGUI = GUICreate('')
GUICtrlCreateLabel('Why magic numbers are counter productive.', 5, 5)
GUICtrlSetState(Default, 128) ; Does this hide, show or disable it?
GUICtrlSetState(Default, 64) ; Does this hide, show or disable it?
GUISetState(@SW_SHOW, $hGUI)
While 1
Switch GUIGetMsg()
Case -3 ; Doesn't really tell much about what it does.
ExitLoop
Case -4, -5 ; Again, no idea what these are. MouseMove? MouseClick? Restore?
MsgBox(4096, '', 'Do something when this action takes place.')
EndSwitch
WEnd
GUIDelete($hGUI)
EndFunc ;==>Example
Did you understand the numbers were these:
#include <GUIConstantsEx.au3>
Example()
Func Example()
Local $hGUI = GUICreate('')
GUICtrlCreateLabel('Why magic numbers are counter productive.', 5, 5)
GUICtrlSetState(Default, $GUI_DISABLE) ; Better, this is documented in the help file.
GUICtrlSetState(Default, $GUI_ENABLE) ; Better, this is documented in the help file.
GUISetState(@SW_SHOW, $hGUI)
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE ; Better, this is documented in the help file. Ah, it's the close action.
ExitLoop
Case $GUI_EVENT_MINIMIZE, $GUI_EVENT_RESTORE ; Better, this is documented in the help file.
MsgBox($MB_SYSTEMMODAL, '', 'Do something when this action takes place.') ; Better, this is documented in the help file.
EndSwitch
WEnd
GUIDelete($hGUI)
EndFunc ;==>Example
Include-once directive
This one is designed for standard includes and UDFs, it's highly recommended to use it.
Those includes may be included in more than one script of your project because they are needed for some includes or your script itself. In that case, the code will be duplicated which is not a good thing especially if you have (and it's mainly the case) constants declared in those files, in so far as the constants cannot be redeclared/reassigned; same thing for functions.
Put the directive in top of your UDF (library) to avoid itself to be included more than once :
#include-once