Scala的新手,并寻找指向惯用解决方案的指针,如果有的话.
我想要将一些用户提供的任意Scala函数(允许引用我在代码中定义的函数/类)应用于某些数据.
例如:我有我的功能foo(s: String): String和bar(s: String): String功能myprog.scala.用户像这样运行我的程序:
$ scala myprog data.txt --func='(s: Str) => foo(bar(s)).reverse'
Run Code Online (Sandbox Code Playgroud)
这将逐行遍历数据文件,并发出将用户指定的函数应用于该行的结果.
对于额外的积分,我可以确保用户定义的功能没有副作用吗?如果没有,我可以将功能限制为仅使用有限的功能子集(我可以保证安全)吗?
@kenjiyoshida 有一个很好的要点,展示了如何评估 Scala 代码。请注意,当从该要点使用时Eval,如果 Scala 默认为 inferring ,则不指定返回值将导致运行时失败Nothing。
scala> Eval("println(\"Hello\")")
Hello
java.lang.ClassCastException: scala.runtime.BoxedUnit cannot be cast to scala.runtime.Nothing$
... 42 elided
Run Code Online (Sandbox Code Playgroud)
与
scala> Eval[Unit]("println(\"Hello\")")
Hello
Run Code Online (Sandbox Code Playgroud)
它也可以很好地处理范围内的任何内容。
object Thing {
val thing: Int = 5
}
object Eval {
def apply[A](string: String): A = {
val toolbox = currentMirror.mkToolBox()
val tree = toolbox.parse(string)
toolbox.eval(tree).asInstanceOf[A]
}
def fromFile[A](file: File): A =
apply(scala.io.Source.fromFile(file).mkString(""))
def fromFileName[A](file: String): A =
fromFile(new File(file))
}
object Thing2 {
val thing2 = Eval[Int]("Thing.thing") // 5
}
Run Code Online (Sandbox Code Playgroud)
Twitter 的util包曾经有util-eval,但现在似乎已被弃用(并且在编译时还会触发编译器错误)。
至于你问题的第二部分,答案似乎是否定的。即使您禁用默认值Predef并自行导入,用户也始终可以使用完全限定的包名称来访问这些函数。您也许可以使用 Scalascala.tools.reflect.ToolBox首先解析您的字符串,然后与白名单进行比较,然后再传递给eval,但此时事情可能会变得非常棘手,因为您将手动编写代码来清理 Scala AST(或者至少拒绝危险的输入)。这绝对不是一个“惯用的解决方案”。
| 归档时间: |
|
| 查看次数: |
3233 次 |
| 最近记录: |