Beginning Tips for Writing AutoHotkey Scripts (Functions as Building Blocks)

In previous discussions, the modularity of AutoHotkey is highlighted. That means AutoHotkey scripts are composed of a series of building blocks many of which stand alone and are completely independent of the rest of the code. This concept is important since breaking down a script into these modules makes it easier to understand and debug an application.Cover 250 Border The beauty of making maximum use of these independent bricks is that with only a few exceptions they can appear almost anywhere in the script without affecting its operation. Now it’s time to discuss the AutoHotkey building blocks which are probably the most powerful and flexible of all the modules: Functions.

The benefit to using Functions is that virtually any snippet of code can be turned into a Function which, once defined, can be inserted as a command to run that code anywhere in the script. Or, if set up to return a value, the Function can act as an expression for calculation or evaluation—again anywhere in the script. This can make your scripts much easier to organize and understand while saving you from writing a great deal of redundant code. By using Functions you’re actually writing new commands and/or expressions for your AutoHotkey scripts.

User-defined Function Format

Functions have much in common with Label subroutines (discussed in the last Blog and the Blog previous to the last) and act in a manner similar to Label subroutines. But, unlike a Label, a Function can be called directly from almost anywhere in the script by merely invoking the Function name (e.g. MyFunction()) as a command within the running script. For example, using the same code from last time, the Label subroutine GetTime: is converted to the Function GetTime():

GetTime()
{
  FormatTime, OutputVar
  MsgBox, The time is %OutputVar%
}

The Function GetTime() serves the same purpose as the previous Label GetTime:. When the Function is called the current date and time is formatted with the FormatTime command, then displayed with the MsgBox command. The primary differences between the Label format and Function format are:

(1)  The Function name in the definition is always followed by a set of parentheses (rather than a colon) which optionally may contain the names of variable parameters passed to the Function.

(2) The Function code is contained within a set of curly brackets ({…}) rather than terminated with the Return command. (The Return command may be used within a Function to return a value to the calling routine.)

By making these two changes (as seen above) the Label subroutine GetTime: is converted to the GetTime() Function serving the exact same purpose (displaying the current time and date).

As a code module, a Function definition can appear almost anywhere in an AutoHotkey script except inside another Function—including (although not recommended) in the middle of the auto-execute section at the beginning of the script. When the script is first loaded AutoHotkey scans the entire file for Functions, in the same manner as hotstring and hotkey definitions, loading all Functions into memory prior to running the auto-execute section of the script. Functions can be maintained in a separate file and loaded with the #Include command.

Calling a Function

By itself, the loaded Function definition just sits there waiting to be called. It must be invoked within the script before it will do anything. The power of a Function is that it can act as a command or an expression. When inserted on its own into a script, it will act as a command and immediately execute the subroutine. For example, by placing the Function name GetTime() in the auto-execute section of the script (as shown below) it is immediately called upon loading.

GetTime()           ;inserted as a command
Return

^!t::GetTime()      ;added as a hotkey combination

GetTime()
{
  FormatTime, OutputVar
  MsgBox, The time is %OutputVar%
}

Also, unlike a Label subroutine, a Function can be directly assigned to a hotkey combination (^!t::GetTime()) without using the HotKey command. (In the current version of AutoHotkey, many of the commands which previously accepted Label names, but not Functions, now will accept the use of Functions. See the individual documentation for details and usage.)

A Function can also be used as an expression to return a calculated value:

Now := GetTime()    ;a function value assigned to a variable
MsgBox, The time is %Now%
Return
GetTime()
{
  FormatTime, OutputVar
  Return OutputVar   ;value returned to calling variable
}

In this example, rather than both calculating the current date and time then displaying it, acting as an expression GetTime() formats the date and time using the Return command to store it to the variable Now.

Local Versus Global Variables

AutoHotkey Library Deal
AutoHotkey Library Deal

One of the most common sources of confusion for new script writers when using Functions is understanding the difference between local and global variables. By default all variables within a Function are local. That means a Function variable only exists inside the Function and cannot be used outside it—even if it uses the same name as another outside variable. (If a variable by the same name exists outside the Function, it will be unaffected by the variable inside the Function.)

This local-only existence of variables is an important feature of Functions because we often include our most useful Functions in various scripts for various purposes. If Function variables were always global (available throughout the entire script) they would inadvertently interfere with other script variables by the same name—causing errors to be introduced into a script by merely including (#Include) our set of useful Functions.

Not understanding this local versus global variable concept can be a source of aggravation for the novice scriptwriter. Beginners often think that a Function is not doing its job when they unknowingly try to use a variable value directly from inside the Function elsewhere in the script. Nothing happens. This is the importance of using the Return command when values from the Function must be saved for later use.

Making Variables Global

There are two other options for making Function variables available elsewhere in a script. The first is to declare a variable as Global within the Function:

GetTime()
MsgBox, The time is %OutputVar%

GetTime()
{
  Global OutputVar     ;OutputVar is now available everywhere
  FormatTime, OutputVar
}

By adding the Global OutputVar command the variable OutputVar is then made available for use anywhere in the script without rerunning the Function. It becomes a universal variable. If you need multiple global variables, then place a comma between them on the same line (e.g. Global OutoutVar, NewVar1, NewVar2,…). If all variables are to be global then merely place the Global command with no variable names at the beginning of the Function script.

In newer versions of AutoHotkey, if a variable is declare global anywhere outside of any function, then it is global everywhere including within all Functions:

Global OutputVar         ;available everywhere
GetTime()
MsgBox, The time is %OutputVar%

GetTime()
{
  FormatTime, OutputVar
}

These are called super-global variables and save the need to declare the variables Global within each Function.

Functions are one of the most useful ways to implement AutoHotkey app features which may need to be reused. If you ever find that you’re rewriting the same or similar code, then it may be time to consider using a Function, as was done in “Writing AutoHotkey Functions to Make Life Easier.”

*         *          *

Part 1: Beginning Tips for Writing AutoHotkey Scripts (Modular Independence of HotStrings)

Part 2: Beginning Tips for Writing AutoHotkey Scripts (Modular Independence of HotKeys)

Part 3: Beginning Tips for Writing AutoHotkey Scripts (Building Blocks Using Labels Containing Subroutines)

Part 4: Beginning Tips for Writing AutoHotkey Scripts (Methods for Running Label Subroutines)

 *          *          *

New to AutoHotkey? See “Introduction to AutoHotkey: A Review and Guide for Beginners.”

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s