jeeswg's functions tutorial

Helpful script writing tricks and HowTo's
User avatar
jeeswg
Posts: 4785
Joined: 19 Dec 2016, 01:58
Location: UK

jeeswg's functions tutorial

24 Dec 2017, 11:58

==================================================

JEESWG'S FUNCTIONS TUTORIAL
[updated: 2018-08-16]

==================================================

CONTENTS

> BUILT-IN / CUSTOM FUNCTIONS
> OUTLINE
> LOCAL / GLOBAL / SUPER-GLOBAL VARIABLES
> STATIC VARIABLES
> BYREF VARIABLES
> VARIADIC FUNCTIONS
> OMIT PARAMETERS: CUSTOM FUNCTIONS / COM OBJECTS

> MULTIPLE INPUT PARAMETERS
> MULTIPLE OUTPUT PARAMETERS
> INPUT PARAMETERS: COUNT
> INPUT PARAMETERS: CHECK IF PARAMETER OMITTED
> DUAL ROLE INPUT/OUTPUT PARAMETER (BYREF AND OBJECTS)
> PARAMETERS ARE CLEARED AFTER USE
> HANDLE BINARY DATA
> PARAMETER VARIABLES VERSUS OTHER VARIABLES
> CREATING VARIABLES DYNAMICALLY WITHIN FUNCTIONS
> REFERRING TO FUNCTIONS DYNAMICALLY
> OVERRIDE BUILT-IN FUNCTIONS
> #INCLUDE PATH, #INCLUDE <LIBNAME> AND AUTO-INCLUDE
> PERFORM ACTIONS AT SCRIPT STARTUP

> FAT ARROW FUNCTIONS
> NESTED FUNCTIONS
> CLOSURES

==================================================

> BUILT-IN / CUSTOM FUNCTIONS

In AutoHotkey you can use built-in functions.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



In AutoHotkey, you can also create custom functions.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



Ultimately you can create functions to do virtually anything. And the vast majority of AutoHotkey's built-in functions can be recreated as custom functions.

Examples of functions:
Explorer window interaction (folder windows/Desktop, file/folder enumeration/selection/navigation/creation) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=35041
GUIs via DllCall: get/set internal/external control text - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=40514
commands as functions (AHK v2 functions for AHK v1) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=37&t=29689
AutoHotkey via DllCall: AutoHotkey functions as custom functions - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=37871

==================================================

> OUTLINE

Here is a guide to the sections that will follow:

Key terms (which will be explained further):
- scope: local/global/super-global variables - a variable has a local version (inside a function), and a global version (outside a function), sometimes these are the same
- static variables - the content of static variables is remembered after a function is executed, normally variables are cleared
- ByRef variables - an input parameter that can also be used as an output parameter
- variadic functions - functions with a variable number of parameters, normally functions have a fixed number of parameters

Ways to increase the number of input variables:
- lots of variables as input parameters
- variables containing comma(/delimiter)-separated lists
- use global variables
- use arrays as input parameters
- variadic functions

Ways to increase the number of output variables:
- note: return is limited to one output parameter
- variables containing comma(/delimiter)-separated lists
- use global variables
- return an array
- use multiple ByRef variables as input/output parameters

Also:
- how many parameters were passed to the function
- omitting parameters / default values
- can an input variable also be an output variable (ByRef, objects)
- are variables inside functions cleared when the function ends
- handling binary data
- are variables inside functions local or global (and: parameter variables versus variables inside the function)
- creating variables dynamically within functions
- referring to functions dynamically
- built-in/custom functions with the same name
- including scripts (and functions) using #Include (and what happens when a function isn't found)
- what happens when a function isn't found
- fat arrow functions (AHK v2)
- nested functions (AHK v2)
- closures (AHK v2)

==================================================

> LOCAL / GLOBAL / SUPER-GLOBAL VARIABLES

- Variables within the body of a function or class definition are either super-global, global or local.
- Variables in the main body of a script are either super-global or global.
- Parameter variables are neither super-global, global nor local, they are special cases.
- It is possible for a global variable, and a variable local to a function, to share the same name, however, they are completely separate variables.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



- Defining a variable as global within the main body of a script (outside a function/class definition) e.g. global var, makes it super-global. All functions will use the global version of that variable, apart from any functions that specify to use their own local(/static) version of that variable e.g. local var or static var.
- Defining a variable as global within a function, means that the global version of the variable is used.
- Parameter variables, those used as parameters when calling the function, e.g. Func(var1, var2, var3) are special cases. They are not global/local/static like the other variables that appear within the body of a function.

- AHK v1: If one or more variables are defined as local, all other (non-parameter) variables in the function are defined as global. This is assume-global mode.
- AHK v2: If one or more variables are defined as local, this does not affect any other variables in the function.

- If one or more variables are defined as global, this does not affect any other variables in the function.
- If one or more variables are defined as static (static variables are local) this does not affect any other variables in the function.

- The word 'global' on its own, can be used to make every variable in a function global by default. This is assume-global mode.
- The word 'static' on its own, can be used to make every variable in a function static (and local) by default. This is assume-static mode.
- Prior to AHK v1.1.27. The word 'local' on its own, cannot be used to make every variable in a function local by default, it triggers an error message.
- From AHK v1.1.27 onwards. The word 'local' on its own, can be used to make every variable in a function local by default. This is force-local mode.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


- Further examples which work on AHK v1.1.27 onwards.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



- Some examples of defining variables within functions:
- The same syntax works for 'local' and 'static'.
- The first line makes all variables global.
- The other lines demonstrate getting/setting the contents of a global variable.
- There is a concrete example in the codebox after.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


Code: [Select all] [Download] GeSHi © Codebox Plus

var1 := "a", var2 := "b"
Func()
MsgBox, % var1 " " var2 ;1 b

Func()
{
global var1 := 1, var2
MsgBox, % var1 " " var2 ;1 b
}


- This example demonstrates that position does not matter when making a variable super-global, but that it does matter when setting the variable's contents.
- The first MsgBox shows that 'global var := 1' does not set the contents of var at the start of the script.
- The second MsgBox suggests that 'global var := 1' did make var super-global.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> STATIC VARIABLES

- Static variables: the contents of a static variable are remembered between function calls. E.g. you could use a static variable to count each time a function is called.
- With a static variable, the only thing that is 'static' ('constant'), is that its contents are remembered between function calls. The variable's address, size, and content can be changed at any time.
- If you use a line such as this: static var := 123, var is only set to that value once (when the script loads), the value is not reset to 123 each time you use the function.
- When the function call is completed, the variable will maintain its value.
- Static lines can be described as 'ghost lines', they are only executed once, after that, they are invisible to the script.

- All static variables are local.
- A local variable is either static or non-static.
- For any (non-parameter) non-static local variables that appear within the body of a function, their content is discarded when the function call has ended.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> BYREF VARIABLES

- ByRef variables provide an input parameter that can also be used as an output parameter.
- Note: if you pass something that isn't a variable/object name, into a ByRef parameter, e.g. 1+1, then the parameter acts as normal, and not as a ByRef parameter.
- Parameters that are not ByRef (by reference), are ByVal (by value).

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> VARIADIC FUNCTIONS

- Variadic functions can have a variable number of parameters.
- They have 0 or more normal parameters, and then a 'variadic parameter'.
- All of the items in the 'variadic parameter' are retrieved as keys in an array by the function. With key names 1, 2, 3 etc.
- ByRef variables cannot be used with the 'variadic parameter'.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> OMIT PARAMETERS: CUSTOM FUNCTIONS / COM OBJECTS

- From v1.1.12 onwards, optional parameters can be omitted in functions. This also made the ComObjMissing function unnecessary.
- However, if you wanted a parameter, used with a COM object, to sometimes be omitted, and to sometimes be used, you could use the alternative mentioned below:
jeeswg's objects tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=29232

Code: [Select all] [Download] GeSHi © Codebox Plus

m := ComObjMissing() ;AHK v1
m := ComObject(0xA, 0x80020004) ;AHK v1/v2

Changes & New Features
https://autohotkey.com/docs/AHKL_ChangeLog.htm#v1.1.12.00
1.1.12.00 - August 14, 2013
Optional parameters can be omitted by writing two consecutive commas, as in InStr(a, b,, 2). Unlike previous versions, this now works for objects (including COM objects) and built-in functions. [a,,b] can be used to create a sparse array.

ComObjActive()
https://autohotkey.com/docs/commands/ComObjActive.htm
Creates an object which may be used in place of an optional parameter's default value when calling a method of a COM object. [v1.1.12+]: This function is obsolete. Instead, simply write two consecutive commas, as in Obj.Method(1,,3)
ParamObj := ComObjMissing()


==================================================

> MULTIPLE INPUT PARAMETERS

Ways to increase the number of input variables.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> MULTIPLE OUTPUT PARAMETERS

Ways to increase the number of output variables.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> INPUT PARAMETERS: COUNT

How many parameters were passed to the function.

Code: [Select all] [Download] GeSHi © Codebox Plus

VariadicFunc(oParams*)
{
return oParams.Length()
}

MsgBox, % VariadicFunc("a") ;1
MsgBox, % VariadicFunc("a", "b") ;2
MsgBox, % VariadicFunc("a", "b", "c") ;3


==================================================

> INPUT PARAMETERS: CHECK IF PARAMETER OMITTED

Omit parameters / default values.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> DUAL ROLE INPUT/OUTPUT PARAMETER (BYREF AND OBJECTS)

Can an input variable also be an output variable. Passing variables ByRef, and passing objects ByRef/non-Byref.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> PARAMETERS ARE CLEARED AFTER USE

Are variables inside functions cleared when the function ends.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> HANDLE BINARY DATA

Using the variable address/ByRef parameters for handling binary data.
Note: in AHK v2, you can output binary data as the return value.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> PARAMETER VARIABLES VERSUS OTHER VARIABLES

Are variables inside functions local or global (and: parameter variables versus variables inside the function).

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> CREATING VARIABLES DYNAMICALLY WITHIN FUNCTIONS

Creating variables dynamically within functions.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> REFERRING TO FUNCTIONS DYNAMICALLY

Referring to functions dynamically.
Either by name, or via a Func object created via Func, or via a BoundFunc object created using Bind() which can also specify the contents for the first n parameters.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> OVERRIDE BUILT-IN FUNCTIONS

Built-in/custom functions with the same name.

Code: [Select all] [Download] GeSHi © Codebox Plus

;the built-in function is overridden
Sqrt(vNum)
{
return "root: " (vNum**0.5)
}
MsgBox, % Sqrt(4)


==================================================

> #INCLUDE PATH, #INCLUDE <LIBNAME> AND AUTO-INCLUDE

Including scripts (and functions) using #Include.
And what happens when a function isn't found (auto-include).

#Include / #IncludeAgain - Syntax & Usage | AutoHotkey
https://autohotkey.com/docs/commands/_Include.htm
A script behaves as though the included file's contents are physically present at the exact position of the #Include directive (as though a copy-and-paste were done from the included file).

APPROACH 1: #Include FileFullPath

To include a file explicitly:
#Include C:\Program Files\AutoHotkey\MyFile.ahk

APPROACHES 2/3:

- These 2 lines serve a similar purpose:
#Include <MyPrefix_MyFunc>
MyPrefix_MyFunc()
- Assuming that the function 'MyPrefix_MyFunc' isn't already defined. Both check 3 'Lib' folders for scripts called 'MyPrefix_MyFunc.ahk', and then check those 3 'Lib' folders for 'MyPrefix.ahk'.

APPROACH 2: #Include <LibName>

To check if 6 possible filenames exist and include the first matching file.
#Include <MyPrefix_MyFunc>

3 library folders are checked: local/user/standard:
%A_ScriptDir%\Lib ;local library
%A_MyDocuments%\Lib ;user library
%A_AhkDir%\Lib ;standard library [there is no such variable in AHK at present][where 'A_AhkDir' would be the dir taken from 'A_AhkPath']

6 files are checked for, listed in the order that they are checked for:
%A_ScriptDir%\Lib\MyPrefix_MyFunc.ahk
%A_MyDocuments%\Lib\MyPrefix_MyFunc.ahk
%A_AhkDir%\Lib\MyPrefix_MyFunc.ahk
%A_ScriptDir%\Lib\MyPrefix.ahk
%A_MyDocuments%\Lib\MyPrefix.ahk
%A_AhkDir%\Lib\MyPrefix.ahk
If no matching file is found, an error is raised:
'Error: Call to nonexistent function.'

APPROACH 3: AUTO-INCLUDE

If a call is done to a function that does not exist:
e.g. 'MyPrefix_MyFunc()'
then that is very similar to doing '#Include <MyPrefix_MyFunc>'
but with one key difference,
again 6 files are checked for a possible match,
however, instead, the file contents are not 'copied and pasted' at the point at which the function was called,
however, the function is executed.
Thus an auto-include 'includes' a script, in the sense that all of its functions are made available for use, however, it does not 'copy and paste' the file contents to a specific point.

Note: If no matching file is found, an error is raised:
'Error: Call to nonexistent function.'

FURTHER NOTE:

- Think of any files that are included as in an abstract place (the error messages even indicate a completely separate line numbering system), away from the main script.
- Both #Include and auto-include cause files to be 'present' in an abstract place. However, any #Include line has an additional effect, any time it is 'executed' in the flow of the script, it effectively does a Gosub to the top of the included script, with a 'return' line at the bottom of the included script.

See also:
#Include <LibName> v. auto-include - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=53647

==================================================

> PERFORM ACTIONS AT SCRIPT STARTUP

A function that will run on script startup (due to 'static').

Code: [Select all] [Download] GeSHi © Codebox Plus

MyFunc()
{
static vDummy := MyFunc()
SoundBeep
MsgBox, % "hello world"
}


Also mentioned here:
GeekDude's tips and tricks - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=7190
Static init functions (was: Goto Eof) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=13&t=4172&p=23235#p23235
jeeswg's documentation extension tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=33596

==================================================

> FAT ARROW FUNCTIONS

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> NESTED FUNCTIONS

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

> CLOSURES

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



==================================================

Return to “Tutorials”

Who is online

Users browsing this forum: No registered users and 1 guest