The Classic Eval() Function Solves Problems You Didn’t Even Know You Had by Calculating and Resolving AutoHotkey Functions and Expressions Found in Text Strings!
When I work on particular AutoHotkey solutions, often I find myself in the middle of a treasure hunt—picking up hidden gems along the way. Although operative for years, I didn’t know these valuable tools existed until I went searching for answers to a seemingly unrelated problem.
For example, the simple question about capitalizing sentences led me to the RegExHotstrings() function discussed last time. As I dug deeper into the math-side of dynamic Hotstrings, I discovered the Eval() function. While many old AutoHotkey hands have employed the Eval() function for years, I didn’t understand its power until I used it in the investigation. (Even now the Eval() function does way more than I comprehend. I’ve only scratched the surface of its capabilities.)
The origins of Pulover’s Eval() function started in 2011 with Uberi’s ExprEval() function. In 2016, Pulover (of Pulover’s Macro Creator fame) added a significant number of improvements. The Eval() function now includes many more features than I can explain—but you can see that for yourself. At Pulovers’s GitHub download site, you can download an example script for viewing a number of Eval() possibilities and a test script for playing with the function in realtime. But the math capability—without a ton of gymnastics—caught my attention.
The Eval() Function
The Eval() function allows you to determine on-the-fly the value of one or more AutoHotkey expressions found in text strings. Rather than producing results by writing complex parsing and pasting routines, simply enter the expression into Eval() as the first parameter:
Total := Eval("23+34-345/9")
Eval() places the result from the first parameter into the array variable Total[1]:
Total[1] ⇒ 18.666667
To evaluate multiple expressions, place a comma between the items (inside the quotes):
Total := Eval("23+34-345/9,Round(Sqrt(64))")
The function saves the value of the second expression in the array variable Total[2]:
Total[1] ⇒ 18.666667 Total[2] ⇒ 8
The Eval() function also runs string functions:
Total := Eval("23+34-345/9,Round(Sqrt(64)),SubStr("Hello",1,4)")
The array variable Total[3] contains the first four letters of the word “Hello”:
Total[1] ⇒ 18.666667 Total[2] ⇒ 8 Total[3] ⇒ Hell
In order to view a result, you must display one of the array items—often the first (i.e. Total[1]).
So far, I’ve used the function primarily for math. How you use Eval() depends totally upon your own creativity.
Build Math Hotstrings Using the Eval() Function
To use the Eval() function in your scripts, copy (or #Include) the function code in the script or one of your AutoHotkey libraries (..\Lib\)—which will also #Include the function at runtime.
In this next example, I solve the math-totaling Hotstring problem from the last blog with a simple call by the RegExHotstrings() function to a subroutine (Math) using the Eval() function. The script sets up the dynamic Hotstring using the following RegEx:
MathRegEx := "(\(?\d+(\.\d+)?[+-/*()]+(\d+(\.\d+)?[+-/*()]+)*\d+(\.\d+)?)="
RegExHotstrings(MathRegEx,"Math")
Note: I could have word-wrapped the RegEx using line continuation in any number of places but I left it intact for clarity and copying. Although it may not appear as one line on your screen, if you copy-and-paste it into a script it should paste as a single-line.
When hitting the equal sign ( = ) to activate the dynamic Hotstring, the captured RegEx uses the Eval() function in the Math subroutine:
Math: Result := Eval($1) SendInput, % Format("{:g}", Result[1]) Return
Much simpler than my last approach, this allows much greater diversity in the evaluating math expressions—including multiplication ( * ), division ( / ), the use of parentheses (…) for prioritizing math operations, and more.
Note: I changed the math operator portion of the RegEx to use a range, then adding the needed operators. The range [+-/*()]+ matches any symbol within the square brackets […] one or more times in a row ( + ).
The typed expression “(34+56)/2” followed by an equal sign ( = ) yields “45”:
(34+56)/2= ⇒ 45
Quite frankly, while this works most of the time (especially for simple calculations), I found it inconsistent when entering more complicated expressions using parentheses and various other math operators. (I think that the RegExHotstring() function resets itself too often when I either make corrections or hit the backspace key.) It makes more sense to add the Eval() function to a Windows Clipboard routine and pre-select the expression for evaluation. I will keep this approach in my toolbox for simple dynamic Hotstrings such as the percent % calculation (4/5% ⇒ 80.0%) discussed last time, but longer calculating strings behave more reliably in a Clipboard routine.
The Eval() Function Clipboard Routine
Adding the Eval() function to a Clipboard routine makes possible the immediate evaluation of any selected AutoHotkey expression without writing additional code or running another script. Whether in a document, text editing window, or any other non-editing digital window, you can check the value of an AutoHotkey expression by highlighting it on the computer screen and hitting the Hotkey combination. If you use the tool in an open editing window, then you can include a text replacement option:
!=:: OldClipboard := ClipboardAll Clipboard := "" ; Clears the Clipboard SendInput ^c ; Copy text ClipWait 0 ;pause for Clipboard data If ErrorLevel { MsgBox, No text selected! } Value := Eval(Clipboard) ; Evaluate expression Sleep, 100 MsgBox,4,Eval("%Clipboard%"), % "The value of " . Clipboard . " is " . Value[1] . "!`r`rReplace? (Y/N)" IfMsgBox Yes SendInput % Value[1] Clipboard := OldClipboard Return
With this routine loaded, select any AutoHotkey expression and immediately evaluate it by pressing the Alt+Equal Hotkey combination (Alt=). For example, if you encounter the math operation “(23+45)/15+6” in a document, merely highlight it and press Alt+Equal (!=). A message box pops up displaying both the expression and the answer—then provides an option to replace the original expression with the solution (Yes/No).
When evaluating long, complicated expressions, I found this approach much more robust that attempting to use the dynamic Hotstring previously discussed. While the dynamic Hotstring may work most of the time—especially for short expressions—its inconsistency in more complex calculations leads me to prefer the Clipboard routine approach.
Downloading the Eval() Function
You can download the Eval() function and other related scripts directly from a variety of sources starting with the AutoHotkey Forum or Pulover’s GitHub post. You can also download an Eval() Function ZIP file here—which includes the Eval.ahk function file, EvalExamples.ahk script, and EvalTester.ahk script. Plus, I’ve posted the files at the ComputorEdge Free AutoHotkey Scripts page.
Click the Follow button at the top of the sidebar on the right of this page for e-mail notification of new blogs. (If you’re reading this on a tablet or your phone, then you must scroll all the way to the end of the blog—pass any comments—to find the Follow button.)
This post was proofread by Grammarly
(Any other mistakes are all mine.)
(Full disclosure: If you sign up for a free Grammarly account, I get 20¢. I use the spelling/grammar checking service all the time, but, then again, I write a lot more than most people. I recommend Grammarly because it works and it’s free.)
Find my AutoHotkey books at ComputorEdge E-Books!
Wow, how have I missed out on this function? I comb through the current and archived Autohotkey forums all the time. Thanks so much for this. I can really use it.
LikeLike
[…] blogs, “Dynamic Regular Expressions (RegEx) for Math Calculating Hotstrings” and “The Eval() Function for Hotkey Math Calculations and Text Manipulation“, I highlighted two different powerful, auxiliary (not built-in) AutoHotkey functions: […]
LikeLike