"Eval" in Scala

eval in Scala

Scala is not a scripting language. It may look somewhat like a scripting language, and people may advocate it for that purpose, but it doesn't really fit well within the JSR 223 scripting framework (which is oriented toward dynamically typed languages). To answer your original question, Scala does not have an eval function just like Java does not have an eval. Such a function wouldn't really make sense for either of these languages given their intrinsically static nature.

My advice: rethink your code so that you don't need eval (you rarely do, even in languages which have it, like Ruby). Alternatively, maybe you don't want to be using Scala at all for this part of your application. If you really need eval, try using JRuby. JRuby, Scala and Java mesh very nicely together. It's quite easy to have part of your system in Java, part in Scala and another part (the bit which requires eval) in Ruby.

Dynamic code evaluation in scala

You could use either scala-lang API for that or twitter-eval. Here is the snippet of a simple use case of scala-lang

import scala.tools.nsc.Settings
import scala.tools.nsc.interpreter.IMain

object ScalaReflectEvaluator {

def evaluate() = {
val clazz = prepareClass
val settings = new Settings
settings.usejavacp.value = true
settings.deprecation.value = true

val eval = new IMain(settings)
val evaluated = eval.interpret(clazz)
val res = eval.valueOfTerm("res0").get.asInstanceOf[Int]
println(res) //yields 9
}

private def prepareClass: String = {
s"""
|val x = 4
|val y = 5
|x + y
|""".stripMargin
}
}

or with twitter:

import com.twitter.util.Eval

object TwitterUtilEvaluator {

def evaluate() = {
val clazz = prepareClass
val eval = new Eval
eval.apply[Int](clazz)
}

private def prepareClass: String = {
s"""
|val x = 4
|val y = 5
|x + y
|""".stripMargin
}
}

I am not able to compile it at the moment to check whether I have missed something but you should get the idea.

Evaluating Scala with twitter Eval and Scala notebook

Both scala-notebook and twitter-eval use the scala-compiler tool under the hood to compile and interpret the text as scala code. So, technically there is no difference between those two with regard to how they compile the source code.

Just to shed some light on how they both do that, check out the below files:

scala-notebook: https://github.com/Bridgewater/scala-notebook/blob/master/kernel/src/main/scala/com/bwater/notebook/kernel/Repl.scala

twitter-eval: https://github.com/twitter/util/blob/develop/util-eval/src/main/scala/com/twitter/util/Eval.scala

As you can see, both of the use the scala-compiler. The compiler classes and utilities are located in the package 'scala.tools'

val behavior in scala REPL and Intellij

From Scala docs REPL overview:

  • every line of input is compiled separately.
  • dependencies on previous lines are included by automatically generated imports.

Combining these two facts, we can understand that they are not in the same namespace, unlike the example you provided which 2 variables called x are in the same class.



Related Topics



Leave a reply



Submit