4

I could not find how to convert a String into runnable code, for instance:

val i = "new String('Yo')"
// conversion
println(i)

should print

Yo

after the conversion.

I found the following example in another post:

import scala.tools.nsc.interpreter.ILoop
import java.io.StringReader
import java.io.StringWriter
import java.io.PrintWriter
import java.io.BufferedReader
import scala.tools.nsc.Settings

object FuncRunner extends App {

  val line = "sin(2 * Pi * 400 * t)"

  val lines = """import scala.math._
    |var t = 1""".stripMargin

  val in = new StringReader(lines + "\n" + line + "\nval f = (t: Int) => " + line)
  val out = new StringWriter

  val settings = new Settings

  val looper = new ILoop(new BufferedReader(in), new PrintWriter(out))
  val res = looper process settings
  Console println s"[$res] $out"
}

link: How to convert a string from a text input into a function in a Scala

But it seems like scala.tools is not available anymore, and I'm a newbie in Scala so i could not figure out how to replace it. And may be there are just other ways to do it now.

Thanks !

Community
  • 1
  • 1
Charrette
  • 690
  • 1
  • 11
  • 29

4 Answers4

6

You can simple execute your code contained inside String using Quasiquotes(Experimental Module).

import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox

// TO compile and run code we will use a ToolBox api.
val toolbox = currentMirror.mkToolBox()

// write your code starting with q  and put it inside double quotes.
// NOTE : you will have to use triple quotes if you have any double quotes usage in your code.
val code1 = q"""new String("hello")"""
//compile and run your code.
val result1 = toolbox.compile(code1)()

// another example
 val code2 = q"""
 case class A(name:String,age:Int){
    def f = (name,age)
 }
 val a = new A("Your Name",22)
 a.f
 """

 val result2 = toolbox.compile(code2)()

Output in REPL :

// Exiting paste mode, now interpreting.

import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
toolbox: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@69b34f89
code1: reflect.runtime.universe.Tree = new String("hello")
result1: Any = hello
code2: reflect.runtime.universe.Tree =
{
  case class A extends scala.Product with scala.Serializable {
    <caseaccessor> <paramaccessor> val name: String = _;
    <caseaccessor> <paramaccessor> val age: Int = _;
    def <init>(name: String, age: Int) = {
      super.<init>();
      ()
    };
    def f = scala.Tuple2(name, age)
  };
  val a = new A("Your Name", 22);
  a.f
}
result2: Any = (Your Name,22)

scala> 

To learn more about Quasiquotes : http://docs.scala-lang.org/overviews/quasiquotes/setup.html

curious
  • 2,908
  • 15
  • 25
2

I found a simple solution using the ToolBox tool :

val cm = universe.runtimeMirror(getClass.getClassLoader)

val tb = cm.mkToolBox()

val str = tb.eval(tb.parse("new String(\"Yo\")"))

println(str)

This is printing:

Yo
Charrette
  • 690
  • 1
  • 11
  • 29
  • 1
    I am not able to find this scala.tools.reflect.ToolBox library...can you please help me with this.... – Aamir Nov 07 '19 at 18:21
1

The scala compiler (and the "interpreter loop") are available here. For example:

https://github.com/scala/scala/blob/v2.11.7/src/repl/scala/tools/nsc/interpreter/ILoop.scala

A compiled jar that has that class will be in your scala distribution under lib\scala-compiler.jar.

Tilo
  • 3,255
  • 26
  • 31
  • But on there website http://scala-tools.org/, they are saying "We are no longer providing any support for scala-tools.org.", are they only talking about the website? If they're also talking about the library, it might be unwise to use it right? – Charrette Jun 26 '15 at 08:34
  • @Charrette: The scala compiler is actually maintained by Typesafe. So it's safe to use it. – Tilo Jun 26 '15 at 22:46
-2

One way could be to take/parse that string code and then write it yourself in some file as Scala code. This way it would be executed by Scala compiler when you will call it.

An example: just like Scala is doing with Java. It takes this code and then convert it into Java by making use of main method.

object Xyz extends App {
 println ("Hello World!")
}
R Sun
  • 1,353
  • 14
  • 17