NamedArgs Object

class NamedArgs extends Map

Keysharp extension. This class does not exist in AutoHotkey v2.

Carries the named arguments of one call. It is a case-insensitive Map whose keys are the parameter names, and it behaves like one in every respect but one: passed as the last argument of a call, it supplies that call's named arguments instead of being passed as a value.

Writing f(Alpha: 1) creates one automatically. The class itself is needed only to build a named call whose names are decided at run time, or to inspect the names a variadic function collected. It is exported by the KS module:

#Import "Ks" { NamedArgs }

Table of Contents

NamedArgs()

NamedArgsObj := NamedArgs(Name1, Value1, Name2, Value2, ...)

Takes the same alternating name/value pairs as Map(). An empty container is legal; it supplies no named arguments.

CaseSense is fixed at Off, because parameter names are matched case-insensitively and nothing else would agree with the binder. It cannot be changed.

Reading and writing names

Names are Map keys, so the ordinary item syntax reads and writes them — including names computed at run time, and names that would collide with a member of Object such as Base or Clone, since keys and members share no namespace:

na := NamedArgs()
na["Title"] := "Confirm"
na[NameFromConfig] := Value
na["Base"] := 16            ; an ordinary name, not the object's base

The same syntax reads a container a variadic function collected, along with the rest of Map's interface — na["Title"], na.Has("Title"), na.Count, for Name, Value in na. Each takes the container as the object being operated on, never as an argument, which is what makes them usable here — see below.

Why the position matters

The type carries the meaning, as with a VarRef. As the last argument of any call, a NamedArgs supplies that call's named arguments; anywhere else — including one a variadic call re-emitted before a later positional argument — it is an ordinary value.

The consequence is that a NamedArgs cannot be passed to a function as data: it would name that function's parameters.

Type(na)        ; error: na's names are not parameters of Type
Type([na])      ; "Array" — the Array is the argument, so the container is data inside it

To hand one to a function as a value, pass the Array or object that holds it — the container has to stay inside, since taking it back out puts it in the last argument position again.

Examples

A named call built at run time. The name is not known until the script runs, so it cannot be written as Name: value syntax.

#Import "Ks" { NamedArgs }

Setting := "Title"
MsgBox("Save changes?", NamedArgs(Setting, "Confirm"))

Forwarding, then adding a name. The wrapper's collected arguments already contain the caller's names; adding one of its own unions the two.

#Import "Ks" { NamedArgs }

Confirm(Params*) {
    MsgBox(Params*, Options: "YesNo")
}
Confirm("Save changes?", Title: "Confirm")   ; both Title and Options reach MsgBox

Inspecting what a variadic function collected.

#Import "Ks" { NamedArgs }

Peek(Params*) {
    if Params.Length && Params[Params.Length] is NamedArgs {
        for Name, Value in Params[Params.Length]
            MsgBox Name ": " Value
    }
}
Peek("Save changes?", Title: "Confirm", Options: "OK")

Named parameters, Forwarding through a wrapper, Map, Func.Params, #Warn NamedArg, KS module