Operator Type:
Operator Scope of Action:
Operator Purpose:
Operator First Added:
Operator Altered:
Function [other Function type actions]
Item [operators of similar scope]
Data manipulation [other Data manipulation operators]
Baseline
eval([item,]expression)
The item parameter must be quoted unless an attribute reference. Ways to define item.
The eval() function takes two quoted evaluated (as string) parameters, i.e. the parameters. The first parameter is optional. Thus, in basic form:
if($MyBool){$AttribX = "$Name(parent)+' XYZ'";}else{$AttribX = "$Name(grandparent) + 'ABC'";}; $AttribY = eval($AttribX);
will set AttribY to the name of the current note's parent's title plus string "XYZ" or that of its grandparent plus string "ABC", depending on the value of attribute MyBool by evaluating attribute AttribX. Thus eval() gives the action code result of an attribute rather than its literal value. As such eval is normally applied to string-based attributes.
Further examples
The eval() function can be useful for inserting a local attribute value in an expression that will be evaluated in a different context. Consider this find() in an a rule:
$ArtistCount = find($ArtistName==$Name & !$IsAlias).size;
For each note evaluated, the note's $Name is compared to ArtistName. However, what if the intent was to use this in a note with an artist's name where it is necessary to come the calling note's $Name, not that of the in-scope note. There is no designator for that relationship, but eval() offers a way around:
$ArtistCount = eval('(find($ArtistName=="'+$Name+'" & !$IsAlias).size)');
This first of all makes a string using the correct find code but also inserting the value of the calling note's $Name, and then the whole is evaluated as if it were the original verbatim find() call above.
The process can be made clearer by splitting it into two steps by first using a placeholder $TempString attribute:
$TempString = '(find($ArtistName=="'+$Name+'" & !$IsAlias).size)';
The outer parentheses are simply to ensure the .size() call chained on the end of the find is evaluated with the find(). For a note called "Jacques Brel", $TempString would be the string: (find($ArtistName=="Jacques Brel" & !$IsAlias).size)
. Now, to use eval():
$ArtistCount = eval($TempString);
Side note: the actual scenario above can also be solved using the 'that' designator, although the example holds true as an exploration of how eval() works.
A more complex example, using nested eval() calls is described under 'using long sections of code'.
Macros: eval() can be combined with do(macro). As macros take input arguments, an evaluated macro can work a bit like a code function, taking inputs and returning output that once passed through eval() gives an evaluated result. See the do() operator.
The eval() operator also allows access to two Tinderbox properties that are not available via action syntax or attribute value. There are the current TBX document's filename (sans extension) and the app version of the currently used Tinderbox on the user's Mac:
eval(^docTitle^)
gives a value of "aTbRef-8" (note no '.tbx' extension)
eval(^version^)
gives "8.9.2" (note that you might want to prefix the return string with 'v' or 'v.' thus: "v.8.9.2").
In full syntax form, an additional first parameter is added that is an expression string evaluating as a note name, path or note name. Where specified, this indicates the note from which attribute values in the second parameter should be drawn.
To create an attribute reference ($-prefixed as in '$Name' not 'Name') use action() instead of eval().
Example using both inputs
A different example, using the optional path argument. Take two root-level notes, aa and bb.
$Text(aa) is: 1+1
$Text(bb) is: [nothing]
$Rule(bb) is: $Text=eval("/aa",$Text)
…after a brief delay, the text of note bb becomes 2, i.e. the sum of the expression in aa's text. The parameter "/aa' simply indicates that in this case aa is note at outline root level.
Now change aa's text:
$Text(aa) is: if(1){42}else{1000}
…after a brief delay, the text of note b becomes 42. How? Any if(condition) is a Boolean test trying to get a true/false result. If the condition does not result in an actual Boolean value (e.g. testing the value of a Boolean attribute) a Boolean is coerced from the result. Thus an empty string or set or the number zero equate to false, all other values to true. Thus in aa's text above, the condition (1) equates to true so the result is 42.
Again, replace the text of a with
$Text(aa): $Color=="red"
This is less obvious. When the expression is evaluated, the result will be true if aa is red, and false otherwise. So, $Text(bb) will be empty unless aa is red; if aa's $Color is red,
$Text(bb): true