Code: Select all
Msgbox "var = " var
Code: Select all
mm var
Usage Examples:
Code: Select all
f := i=>i**i
mm f(3) ; prints: f(3) ⟹ 27
mm f(4) ; prints: f(4) ⟹ 256
mm f(3)+f(4) ; prints: f(3)+f(4) ⟹ 283
mm 3.14*4**2 ; prints: 3.14*4**2 ⟹ 50.240000000000002
mm StrSplit("1234") ; prints: StrSplit("1234") ⟹ ["1","2","3","4"]
mm StrSplit("1|2|3|4","|") ; prints: StrSplit("1|2|3|4","|") ⟹ ["1","2","3","4"]
mm A_AhkVersion, A_OSVersion ; prints: A_AhkVersion, A_OSVersion ⟹ "2.1-alpha.7","10.0.19045"
mm [A_AhkVersion, A_OSVersion] ; prints: [A_AhkVersion, A_OSVersion] ⟹ ["2.1-alpha.7","10.0.19045"]
mm A_Year, A_YWeek, A_WDay ; prints: A_Year, A_YWeek, A_WDay ⟹ "2023","202346","7"
mm [1,2,f(3)] ; prints: [1,2,f(3)] ⟹ [1,2,283]
Tooltip(mm(f(3)+f(4))) ; prints: f(3)+f(4) ⟹ 283 (and returning 283 to be fed as argument to Tooltip)
Here's the function.
1. Limitation: if there are 2 mm() calls on the same line, it's not possible for mm() to identify which is the callsite. This is because Error objects give the line number but not the column number of the callsite (compare getColumnNumber() in V8's stack trace API https://v8.dev/docs/stack-trace-api)
2. You need to have a serializer somewhere else in your script in order for mm to properly print arrays, objects, etc. By default it is assumed to be called "JSON.stringify" but you should change the value of SerializeFunc if it's not.
3. Instead of 'printing' via Msgbox, you can configure it to print via Tooltip, StdOut, OutputDebug, or a log file. Just check out the LogFunc variable in the function body.
Code: Select all
mm(args*) {
static LogFunc := { MsgBox: MsgBox, Tooltip: Tooltip, StdOut: (x) => FileAppend(x, "*"), OutputDebug: OutputDebug, LogToFile: (x) => FileAppend(x, "tmp.log") }.MsgBox
, SerializeFunc := { JSON: x => x is Primitive ? x : JSON.stringify(x) }.JSON
, FormatFunc := { Terse: (info) => Format("{1} ⟹ {2}", info.expression, info.value), Verbose: (info) => SerializeFunc(info) }.Terse
, ReadLineFromFile := (file, lineNo) => StrSplit(FileRead(file), "`n", "`r")[lineNo]
, funcName := A_ThisFunc
, FindExpressionInLine := ((line) => RegExMatch(line, "^\s*" funcName " (.+)$", &mo) ? mo[1] : RegExMatch(line, "\b" funcName "\(((?:[^()]+|(?>\((?1)\)))+)\)", &mo) ? Substr(mo[0], StrLen(funcName) + 2, -1) : "Expression not found; line context = " line)
, Cache := Map()
try throw Error(, -1)
catch as err
{
valStr := SerializeFunc(args), args.length ? valStr := SubStr(valStr, 2, -1) : 0
if not Cache.Has(fileLineKey := err.File "//" err.Line)
Cache.Set(fileLineKey, Trim(ReadLineFromFile(err.File, err.Line)))
LogFunc(FormatFunc({ expression: FindExpressionInLine(Cache[fileLineKey]), value: valStr, file: err.File, lineNo: err.Line, lineText: Cache[fileLineKey] }))
}
return args.length == 1 ? args[1] : args
}