How to compile/eval a Scala expression at runtime? -
new scala , looking pointers idiomatic solution, if there one.
i'd have arbitrary user-supplied scala functions (which allowed reference functions/classes have defined in code) applied data.
for example: have foo(s: string): string
, bar(s: string): string
functions defined in myprog.scala
. user runs program this:
$ scala myprog data.txt --func='(s: str) => foo(bar(s)).reverse'
this run line line through data file , emit result of applying user-specified function line.
for points, can ensure there no side-effects in user-defined function? if not, can restrict function use only restricted subset of functions (which can assure safe)?
@kenjiyoshida has nice gist shows how eval scala code. note when using eval
gist, not specifying return value result in runtime failure when scala defaults inferring nothing
.
scala> eval("println(\"hello\")") hello java.lang.classcastexception: scala.runtime.boxedunit cannot cast scala.runtime.nothing$ ... 42 elided
vs
scala> eval[unit]("println(\"hello\")") hello
it nicely handles whatever's in scope well.
object thing { val thing: int = 5 } object eval { def apply[a](string: string): = { val toolbox = currentmirror.mktoolbox() val tree = toolbox.parse(string) toolbox.eval(tree).asinstanceof[a] } def fromfile[a](file: file): = apply(scala.io.source.fromfile(file).mkstring("")) def fromfilename[a](file: string): = fromfile(new file(file)) } object thing2 { val thing2 = eval[int]("thing.thing") // 5 }
twitter's util
package used have util-eval
, seems have been deprecated (and triggers compiler bug when compiled).
as second part of question, answer seems no. if disable default predef
, imports yourself, user can functions qualified package name. perhaps use scala's scala.tools.reflect.toolbox
first parse string , compare against whitelist, before passing eval
, @ point things pretty hairy since you'll manually writing code sanitize scala ast (or @ least reject dangerous input). doesn't seem "idiomatic solution."
Comments
Post a Comment