How do chain commands in Scala interpreter? - scala

In windows batch, you chain commands with && operator. How do you do the same in scala interpreter? It looks stupid that I need :load file and call import mainobj._ after every load. Obviously, you want to chain them into one liner.

You could write multiple statements in one line of Scala with ;
scala> val a:Int = 3; val b:Int = 4; println(a+b);
7
a: Int = 3
b: Int = 4
Or first type { then write your commands line by line finishing with }
scala> {
| val x:Int = 1
| val y:Int = 2
| println(x + y)
| }
3
Or you can use :paste to turn on paste mode, and then enter your code.
scala> :paste
// Entering paste mode (ctrl-D to finish)
if (true)
print("that was true")
else
print("false")
// Exiting paste mode, now interpreting.
that was true

Related

val behavior in scala REPL and Intellij

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
}

Scala REPL issue - Multiexpression issue

I am new to scala and getting below exception while using :paste command in REPL
scala> :paste
// Entering paste mode (ctrl-D to finish)
1+2
println("welcome to scala world")
// Exiting paste mode, now interpreting.
<console>:11: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
1+2
^
welcome to scala world
scala>
scala version : Scala code runner version 2.12.3 -- Copyright 2002-2017, LAMP/EPFL and Lightbend, Inc
It's not an exception, just a warning that you can ignore. It warns that in paste mode the expression 1+2 has no effect and the result won't be printed.
If you would enter both of your lines in normal mode the REPL will print the result of each expression.
scala> 1+2
res1: Int = 3
scala> println("welcome to scala world")
welcome to scala world
The second part of the warning is for the case that you intend a multi-line expression where each line is a valid expression, e.g.
scala> :paste
// Entering paste mode (ctrl-D to finish)
1+2
-5
// Exiting paste mode, now interpreting.
<console>:48: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
1+2
^
res1: Int = -5
which is different from
scala> :paste
// Entering paste mode (ctrl-D to finish)
(1+2
-5)
// Exiting paste mode, now interpreting.
res22: Int = -2

Leave out parentheses in method call

I am writing a DSL in Scala where I'd like to achieve a chain of method calls as follows:
def x(i:Int) = i
x 1 equals 1 //doesn't compile
I am not sure why the compiler is happy if I leave out the second parentheses but not the first one:
x(1) equals 1 //works fine
Is there a way to achieve the first version?
You can invoke methods without parenthesis, but not functions.
So the following works:
scala> object Foo {
| def x(i:Int) = i
| }
defined object Foo
scala> Foo x 1
res9: Int = 1
scala> Foo x 1 equals 1
res10: Boolean = true

Scala code to read each line from a file not working as expected

I am trying to read all lines in a file .
But when i try to use the same variable, i am not getting any output
Please look at my below code.
scala> import scala.io.Source
import scala.io.Source
scala> val lines = Source.fromFile("/home/inputfiles/records.txt").getLines
lines: Iterator[String] = non-empty iterator
scala> for(i <- lines)
| {
| println(i)
| }
100,Surender,CHN
101,Raja,CHN
102,Vikram,BNG
103,Vijay,MUM
scala> for(i <- lines)
| {
| println(i)
| }
Why i am not getting any output at second time when i applied the same for loop logic on same variable .
I want to store each line in any collection.
hence i tried using ArrayBuffer..
scala> var myArray = ArrayBuffer[String]()
myArray: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer()
scala> val lines = Source.fromFile("/home/inputfiles/records.txt").getLines
lines: Iterator[String] = non-empty iterator
scala> for(i <- lines)
| {
| myArray += i
| }
scala> myArray
res18: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer(100,Surender,CHN, 101,Raja,CHN, 102,Vikram,BNG, 103,Vijay,MUM)
But I would like to store each line in a List . How do i achieve that?

Get objects out of scala interpreter

I spent hours investigating one topic. I am definitely out of my depth here. What I want is to run the scala interpreter programmatically and be able to extract object values from the interpreter. for example, if I send
val a = 1
val b = a + 1
I want to be able to read out b as an Int, not just a string printed out like
b = 2
The source code is dense. So far I don't see any part which would allow such an extraction. Any experts here who can give me a tip or tell me this is utter nonsense?
How do I get typed objects out of the scala interpreter between sessions?
Use JSR 223.
Welcome to Scala version 2.11.7 [...]
scala> import javax.script._
import javax.script._
scala> val engine = (new ScriptEngineManager).getEngineByName("scala")
engine: javax.script.ScriptEngine = scala.tools.nsc.interpreter.IMain#4233e892
scala> engine.eval("val a = 1")
res0: Object = 1
scala> engine.eval("val b = a + 1")
res1: Object = 2
scala> engine.eval("b").asInstanceOf[Int]
res2: Int = 2