This loosely couples the scripting language, but with the caveats that the functions need to be named, and the returned object needs to be a Map (Rhino does this, but I'm not sure about JRuby).
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
engine.eval("function x() { return { foo: 10 } }");
Object o = ((Invocable)engine).invokeFunction("x");
if (o instanceof Map) {
Map m = (Map<Object, Object>)o;
System.out.println(m.get("foo"));
}
or
CompiledScript script = ((Compilable)engine).compile("(function() { return {bar:20} })()");
System.err.println(((Map)script.eval()).get("bar"));
But you have to cheat and call your function by padding it with (...)()
.