In AutoHotkey, you can leave out arguments in the middle of a built-in function call as so:
MsgBox, 4,, Blah
MouseGetPos,,, MouseWin
You can also create functions with optional parameters à la C++:
Foobar(baz, blah="something")
{
MsgBox baz=%baz%, blah=%blah%
}
However the docs say that when you create a function, you cannot have non-default parameters after a default parameter. Trying to do so will result in an interpreter error saying that the first non-default argument after a default argument requires a default.
Why? What’s wrong with calling it like so?
Foobar(baz, blah="something", blivet)
{
MsgBox baz=%baz%, blah=%blah%, blivet=%blivet%
}
Foobar("cat",,"dog")
Is there a way to create functions with optional parameters in the middle?
When you omit a parameter in a built-in command (not function), what you're really doing is passing an empty string. There are differences between these two cases:
With both MsgBox and MouseGetPos, all parameters are optional.
AutoHotkey 1.1 allows the following with user-defined functions:
Foobar(1,, 3)
Foobar(baz, blah="something", blivet="")
{
MsgBox baz=%baz%, blah=%blah%, blivet=%blivet%
}
This is only possible when the parameter's default value is known (i.e. not when calling a function dynamically).
Allowing the middle parameter to be omitted
If you do not want to change the order of the parameters or make two of the three optional, you can do a bit of "juggling":
Foobar("baz", "blivet")
Foobar("baz", "blah", "blivet")
Foobar(baz, p2, p3="omitted")
{
blah := p3="omitted" ? "default" : p2 ; optional
blivet := p3="omitted" ? p2 : p3 ; required
MsgBox baz=%baz%, blah=%blah%, blivet=%blivet%
}
This way, the function always requires at least two parameters, and you're effectively allowed to omit the parameter in the middle when calling the function. However, you need to reserve a (string or numeric) value to indicate the parameter has been omitted. This can be avoided with AutoHotkey 1.1 by using a variadic function:
Foobar("baz", "blivet")
Foobar("baz", "blah", "blivet")
Foobar(baz, p2, p3*)
{
blah := p3.MaxIndex() ? p2 : "default" ; optional
blivet := p3.MaxIndex() ? p3[1] : p2 ; required
MsgBox baz=%baz%, blah=%blah%, blivet=%blivet%
}
Alternatively, the function can be declared as Foobar(baz, p*)
and you can base your conditionals on p.MaxIndex()
(the number of additional parameters), but in that case, only the first parameter is mandatory.
Two options... (workarounds...)
1. Put all the parameters with default values on the right...
Foobar(baz, blivet, blah="something")
{
MsgBox baz=%baz%, blah=%blah%, blivet=%blivet%
}
Foobar("cat","dog")
2. Define an "empty" default value...
Foobar(baz, blah="something", blivet="")
{
MsgBox baz=%baz%, blah=%blah%, blivet=%blivet%
}
Foobar("cat",,"dog")
I can't say why this is like this, but for now, there is no other way... (unless you modify autohotkey :P )
I guess that built-in functions don't work the same way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With