public class EvaluationEnvironment extends java.lang.Object
An evaluation environment is reusable across several executions. The only exception is when using asModule()
,
as attempts to load a module with the same name as an already loaded one fails.
Each instance of this class uses a dedicated GoloClassLoader
, hence usual rules about classloader delegation
and isolation apply to evaluation environments.
While dynamic code evaluation is useful, it shall still be used with care and parsimony. It is especially important
not to abuse run()
, as each invocation triggers the generation of a one-shot class.
Here is an example usage of this API:
let env = EvaluationEnvironment()
let code =
"""
function a = -> "a."
function b = -> "b."
"""
let mod = env: anonymousModule(code)
let a = fun("a", mod)
let b = fun("b", mod)
println(a())
println(b())
While this class is expected to be used from Golo code, it can also be used as a convenient way to embed Golo into polyglot JVM applications.
Constructor and Description |
---|
EvaluationEnvironment()
Creates an evaluation environment using the current thread context classloader.
|
EvaluationEnvironment(java.lang.ClassLoader parentClassLoader)
Creates an evaluation environment using a parent classloader.
|
Modifier and Type | Method and Description |
---|---|
java.lang.Object |
anonymousModule(java.lang.String source)
Loads an anonymous module.
|
java.lang.Object |
asFunction(java.lang.String source,
java.lang.String... argumentNames)
Evaluates some code as the body of a function and returns it.
|
java.lang.Object |
asModule(java.lang.String source)
Evaluates a complete module string.
|
EvaluationEnvironment |
clearImports()
Clears all import symbols for the next code evaluation requests.
|
java.lang.Object |
def(java.lang.String source)
Defines a function, and returns it.
|
EvaluationEnvironment |
imports(java.lang.String head,
java.lang.String... tail)
Imports symbols.
|
java.lang.Object |
run(java.lang.String source)
Runs some code as the body of a function and returns the value.
|
java.lang.Object |
run(java.lang.String source,
java.util.Map<java.lang.String,java.lang.Object> context)
Runs some code as the body of a function and returns the value.
|
public EvaluationEnvironment()
public EvaluationEnvironment(java.lang.ClassLoader parentClassLoader)
parentClassLoader
- the parent classloader.public EvaluationEnvironment imports(java.lang.String head, java.lang.String... tail)
Each symbol generates an equivalent import
statement in the corresponding Golo code. Calling
imports("foo.Bar", "bar.Baz")
means that the subsequent code evaluations have import foo.Bar
and
import bar.Baz
statements.
Note that this has no effect for asModule(String)
. Also, calling this method several times accumulates
the imports, in order.
head
- the first imported symbol.tail
- the next imported symbols.public EvaluationEnvironment clearImports()
public java.lang.Object asModule(java.lang.String source)
For instance:
let code =
"""
module foo
function a = -> "a!"
function b = -> "b!"
"""
let mod = env: asModule(code)
let a = fun("a", mod)
let b = fun("b", mod)
println(a())
println(b())
source
- the module Golo source code as a string.Class
.Predefined.fun(Class, Object, Object)
public java.lang.Object anonymousModule(java.lang.String source)
asModule(String)
, except that the code does not contain
a module
declaration.
let code =
"""
function a = -> "a!"
function b = -> "b!"
"""
let mod = env: anonymousModule(code)
let a = fun("a", mod)
let b = fun("b", mod)
println(a())
println(b())
source
- the module Golo source code as a string.Class
.Predefined.fun(Class, Object, Object)
public java.lang.Object def(java.lang.String source)
let code = "|a, b| -> (a + b) * 2"
let f = env: def(code)
println(f(10, 20))
source
- the function code.FunctionReference
instance.public java.lang.Object asFunction(java.lang.String source, java.lang.String... argumentNames)
let code = "return (a + b) * 2"
let f = env: asFunction(code, "a", "b")
println(f(10, 20))
source
- the function body source code.argumentNames
- the argument names.FunctionReference
instance.public java.lang.Object run(java.lang.String source)
return
statements
to provide return values, if any.
let code = """println(">>> run")
foreach (i in range(0, 3)) {
println("w00t")
}
return 666"""
env: run(code)
source
- the source to run.null
if no return
statement is used.public java.lang.Object run(java.lang.String source, java.util.Map<java.lang.String,java.lang.Object> context)
run(String)
, but it
takes a set of reference bindings in a map. Each reference is equivalent to a let
statement.
let code = """println(">>> run_map")
println(a)
println(b)
"""
let values = java.util.TreeMap(): add("a", 1): add("b", 2)
env: run(code, values)
source
- the source to run.context
- a map of bindings from name to values.null
if no return
statement is used.