Is there a way to evaluate a arbitrary string from Scala as if the same text was entered into the Scala REPL directly? I mean, I would like to do something like this:
scala> eval("val x = 42")
scala> x
res2: Int = 42
Since the Scala REPL is accepting commands in an eval loop using jline (I believe) and then compiling/interpreting it, there has to be a way to submit an arbitrary line of text. I am willing to hack the Scala REPL if necessary.
No REPL hacking necessary—just switch to power user mode, which gives you access to the current scala.tools.nsc.interpreter.IMain as intp:
scala> :power
** Power User mode enabled - BEEP BOOP SPIZ **
** :phase has been set to 'typer'. **
** scala.tools.nsc._ has been imported **
** global._ and definitions._ also imported **
** Try :help, vals.<tab>, power.<tab> **
scala> intp.interpret("val x = 42")
x: Int = 42
res0: scala.tools.nsc.interpreter.package.IR.Result = Success
scala> x
res1: Int = 42
This works since at least 2.9.1.
Another opportunity is to use Eval from Twitter Utility:
val x: Int = new Eval()("1 + 1")
Related
as expected reassignment is giving error like below in REPL
scala> val a=1
a: Int = 1
scala> a=2
<console>:12: error: reassignment to val
a=2
^
But the below reassignment is not giving error in REPL when a=2 preceded with val.
scala> val a=1
a: Int = 1
scala> val a=2
a: Int = 2
When I execute the below code in Intellij its giving error.
object Test {
def main(args: Array[String]) {
val x = 1
val x = 2
}
}
Why val a=1 and val a=2 are not giving any error in REPL(error if it is only a=2) but error in 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.
The REPL is intended for rapid friction-less experimentation. It would be very annoying if you had to restart from scratch just because you accidentally mistyped val a = 32 when you meant val a = 23.
Therefore, the REPL is designed in such a way that it gives the appearance of breaking the rules of Scala, although it actually doesn't. The code that gets actually compiled corresponding to the code you entered looks a little bit like this:
object line$1 {
val a=1
}
object line$2 {
import line$1._
val a=2
}
as expected reassignment is giving error like below in REPL
scala> val a=1
a: Int = 1
scala> a=2
<console>:12: error: reassignment to val
a=2
^
But the below reassignment is not giving error in REPL when a=2 preceded with val.
scala> val a=1
a: Int = 1
scala> val a=2
a: Int = 2
When I execute the below code in Intellij its giving error.
object Test {
def main(args: Array[String]) {
val x = 1
val x = 2
}
}
Why val a=1 and val a=2 are not giving any error in REPL(error if it is only a=2) but error in 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.
The REPL is intended for rapid friction-less experimentation. It would be very annoying if you had to restart from scratch just because you accidentally mistyped val a = 32 when you meant val a = 23.
Therefore, the REPL is designed in such a way that it gives the appearance of breaking the rules of Scala, although it actually doesn't. The code that gets actually compiled corresponding to the code you entered looks a little bit like this:
object line$1 {
val a=1
}
object line$2 {
import line$1._
val a=2
}
Version of Scala I am using is Scala 2.12.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_121) and the Jline Library present is 2.14.3 .
This could sound silly but I am trying to figure out the problem when trying to create a scala file using editor cmd line vi or vim during the Scala REPL mode its throwing error. Below is my error .. Could you please let me know if there is any specific Scala Terminal console that I am suppose to use or am I doing something wrong ?
scala> vi test1.scala
<console>:1: error: ';' expected but '.' found.
vi test1.scala
I am able to do a VI and VIM as well in my system without the SCALA REPL mode but when I am in REPL I am not able to create a scala script file and execute it . What could be wrong ? Is there any settings that needs to be enabled for this ?
For saving your REPL history, use :save file.
There is limited support for using an external editor. The result of the edit is run immediately. After a reset, only the edited lines are in session history, so save will save only those lines.
$ EDITOR=gedit scala
Welcome to Scala 2.12.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_111).
Type in expressions for evaluation. Or try :help.
scala> val x = 42
x: Int = 42
scala> println(x)
42
scala> :edit -2
+val x = 17
+println(x)
17
x: Int = 17
scala> :hi 3
1896 val x = 17
1897 println(x)
1898 :hi 3
scala> :reset
Resetting interpreter state.
Forgetting this session history:
val x = 42
println(x)
val x = 17
println(x)
Forgetting all expression results and named terms: $intp, x
scala> :ed 1896+2
+val x = 5
+println(x)
5
x: Int = 5
scala> :save sc.sc
scala> :load sc.sc
Loading sc.sc...
x: Int = 5
5
I am running Scala 2.9.2 REPL and if I copy&paste following method:
def isPrime(num: Int): Boolean = {
val ceiling = math.sqrt(num.toDouble).toInt
(2 to ceiling) forall (x => num % x != 0)
}
..from the file with a source code (where it works well) to the Interactive Interpreter. I get this exception:
java.lang.IllegalArgumentException: != 0): event not found
at jline.console.ConsoleReader.expandEvents(ConsoleReader.java:426)
...
The problem is the ! character (methods without exclamation mark works well).
Is there any way to make the method work in the REPL?
You might have missed this instance:
https://issues.scala-lang.org/browse/SI-7650
But the paulp fix isn't backward compatible.
scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
** :phase has been set to 'typer'. **
** scala.tools.nsc._ has been imported **
** global._, definitions._ also imported **
** Try :help, :vals, power.<tab> **
scala> $r.r.in.asInstanceOf[scala.tools.nsc.interpreter.JLineReader].consoleReader.setExpandEvents(false)
scala> 1 != 2
res1: Boolean = true
as opposed to crashing on 2.11:
scala> 1 != 2
java.lang.IllegalArgumentException: != 2: event not found
I wasn't able to overcome this issue with the original installation, but installing new version of Scala helped. Perhaps, it is issue of Fedora 17 rpm Scala package.
Related bug
rpm package with "broken" REPL
Is there a quick command? I don't want to Ctrl+d and run Scala everytime I want to clear all variables. reset, clear and clean don't work and :help doesn't have anything listed
You can use :reset
Welcome to Scala version 2.10.0-RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_37).
Type in expressions to have them evaluated.
Type :help for more information.
scala> val a = 1
a: Int = 1
scala> val b = 3
b: Int = 3
scala> :reset
Resetting interpreter state.
Forgetting this session history:
val a = 1
val b = 3
Forgetting all expression results and named terms: $intp, a, b
scala>