Twitter’s Eval can be used to Dynamically compile and use the Code in your application thus making it very effective for Dynamic Programming.
Maven Dependency
Mvnrepository
<dependency>
<groupId>com.twitter</groupId>
<artifactId>util-eval_${scala-minor.version}</artifactId>
<version>${twitter-util-eval.version}</version>
</dependency>
The Eval Function evaluates files, strings, or input streams as Scala code, and returns the result.
val eval = new Eval(target : scala.Option[java.io.File])
The eval function takes a single parameter Target. If the target is None, the results are compiled to memory (and are therefore ephemeral). If target is Some(path), the path must point to a directory, and classes will be saved into that directory.
The flow of evaluation is:
- extract a string of code from the file, string, or input stream
- run preprocessors on that string
- wrap processed code in an apply method in a generated class
- compile the class
- contruct an instance of that class
- return the result of apply()
Declare an Interface which your Dynamic Code should Follow
For the Example I’ve declared a variable name and a function orderString in my trait.
package com.example
trait EvalInterface extends Serializable {
val name:String
def orderString(i: String): String
}
The Dynamic Code which would be evaluated at runtime
Saving the file in the location /path/tsv.scala
package com.example.EvalInterface
new EvalInterface {
override val name:String="TSV"
override def orderString(i: String): String = {
i.splitBy(",").mkString("\t")
}
}
Saving the file in the location /path/csv.scala
package com.example.EvalInterface
new EvalInterface {
override val name:String="CSV"
override def orderString(i: String): String = {
i.splitBy(",").mkString(",")
}
}
Now we can Load these files at runtime to execute the functions
The Dynamic Code Evaluation
package com.example
import com.twitter.util.Eval
import java.io.File
object EvalExample extends App {
val eval = new Eval // Initializing The Eval without any target location
val csvEval: EvalInterface = eval[EvalInterface](new File("/path/csv.scala"))
val tsvEval: EvalInterface = eval[EvalInterface](new File("/path/tsv.scala"))
val records = Array(
"1,2,3,4,5",
"9,8,7,6,5"
)
println(csvEval.name)
records.foreach( i => println(csvEval.orderString( i )))
println(tsvEval.name)
records.foreach( i => println(tsvEval.orderString( i )))
}