Runtime evaluation: Difference between revisions

Line 1,313:
<lang perl>my ($a, $b) = (-5, 7);
$ans = eval 'abs($a * $b)'; # => 35</lang>
 
=={{header|Phix}}==
The eval() function can be used to run fragments of code. The code is run in a brand new context and
hence must be valid in a standalone sense, and cannot directly reference any external identifiers.
Any existing data that needs to be accessed must be provided via the ival and/or iset parameters, and
any results must be explicitly requested via the rset parameter, and any updates applied/extracted
once eval() returns. Passing large tables into and out of the eval context is actually quite efficient,
though some careful refcount management may improve performance, as detailed in the docs.<br>
<!--<lang Phix>(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Runtime_evaluation.exw</span>
<span style="color: #008080;">without</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.1"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">include</span> <span style="color: #7060A8;">eval</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> <span style="color: #000080;font-style:italic;">-- (not an autoinclude, pulls in around 90% of the interpreter/compiler proper)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">code</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
integer i = 0
bool r_init = false
sequence r
if not r_init then r = {} end if
for k=1 to 4 do
i += k
r &= k
end for
"""</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">eval</span><span style="color: #0000FF;">(</span><span style="color: #000000;">code</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"i"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"r"</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- prints {10,{1,2,3,4}}</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">eval</span><span style="color: #0000FF;">(</span><span style="color: #000000;">code</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"r"</span><span style="color: #0000FF;">},{{</span><span style="color: #008000;">"r_init"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"r"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">}}})</span> <span style="color: #000080;font-style:italic;">-- prints {5,1,2,3,4}</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">eval</span><span style="color: #0000FF;">(</span><span style="color: #000000;">code</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"i"</span><span style="color: #0000FF;">},{{</span><span style="color: #008000;">"i"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15</span><span style="color: #0000FF;">}})</span> <span style="color: #000080;font-style:italic;">-- prints {25}</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">eval</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`puts(1,"Hello World\n")`</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- prints Hello World</span>
<!--</lang>-->
{{out}}
<pre>
{10,{1,2,3,4}}
{{5,1,2,3,4}}
{25}
Hello World
</pre>
 
===Evaluating expressions===
Just as a bare (say) "3+4" in a normal source code file would trigger a syntax error, so too would
passing that directly to the eval() function. However it is of course trivial to assign the result
of an expression to a (newly declared) variable and return that:
<!--<lang Phix>(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">eval_expression</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">object</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">eval</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"object x = %s"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">expr</span><span style="color: #0000FF;">}),{</span><span style="color: #008000;">"x"</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">eval_expression</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"3+4"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- prints 7</span>
<!--</lang>-->
 
===Sandboxing===
It is perfectly possible to add a "with safe_mode" prefix to the code passed to eval(), however any runtime error message generated appears to use the wrong symbol table, and therefore is largely gibberish, but at least it blocks dangerous things properly. Slightly better or more readable error messages may be produced by compiling the program, as in the one that invokes eval(), instead of interpreting it.
 
=={{header|PHP}}==
7,805

edits