"Function object" usually means any of the following:
Function objects can be used with the following:
User-defined function objects should follow this general pattern:
class YourClassName { Call(a, b) { ; Declare parameters as needed, or an array*. ;... } __Call(method, args*) { if (method = "") ; For %fn%() or fn.() return this.Call(args*) if (IsObject(method)) ; If this function object is being used as a method. return this.Call(method, args*) } ;... }
Exactly which parts are needed depends on the usage:
method
is an empty string if the script used %this%()
or this.()
.IsObject(method)
is true and method
contains a reference to the target object. For example, if x.y
refers to this
function object, x.y()
→ this[x]()
→ this.__Call(x)
→ this.Call(x)
.The work can also be done directly in __Call. However, having __Call redirect to Call is recommended to ease the transition to AutoHotkey v2, which will change the behaviour of %this%()
and method calls to call the Call method directly.
If you are defining multiple function object types, boilerplate code should be delegated to a base class (but if you'll ever combine your code with someone else's, be wary of conflicts). For example:
class FunctionObject { __Call(method, args*) { if (method = "") return this.Call(args*) if (IsObject(method)) return this.Call(method, args*) } }
The following example defines a function array which can be called; when called, it calls each element of the array in turn.
class FuncArrayType extends FunctionObject { Call(obj, params*) { ; Call a list of functions. Loop % this.Length() this[A_Index].Call(params*) } } ; Create an array of functions. funcArray := new FuncArrayType ; Add some functions to the array (can be done at any point). funcArray.Push(Func("One")) funcArray.Push(Func("Two")) ; Create an object which uses the array as a method. obj := {method: funcArray} ; Call the method. obj.method("foo", "bar") One(param1, param2) { ListVars MsgBox } Two(param1, param2) { ListVars MsgBox }
Acts like a function, but just passes predefined parameters to another function.
There are two ways that BoundFunc objects can be created:
BoundFunc objects can be called as shown in the example below. No other methods are supported. When the BoundFunc is called, it calls the function or method to which it is bound, passing any bound parameters followed by any which were passed by the caller. For example:
fn := Func("RealFn").Bind(1) %fn%(2) ; Shows "1, 2" fn.Call(3) ; Shows "1, 3" RealFn(a, b) { MsgBox %a%, %b% }
ObjBindMethod() can be used to bind to a method when it isn't possible to retrieve a reference to the method itself. For example:
file := FileOpen(A_ScriptFullPath, "r") getLine := ObjBindMethod(file, "ReadLine") MsgBox % %getLine%() ; Shows the first line of this file.
For a more complex example, see SetTimer.