Could someone explain to me why given the object:
object HelloWord {
println("hello world")
var z = 1
z += {
println("adding 1 to z")
1
}
}
running the following code in the REPL gives:
import HelloWorld._
// no output
z
// hello world
// adding 1 to z
// res0: Int = 2
z
// res1: Int = 2
To clarify, I would like an explanation of the output for each line of code entered into the REPL.
Cheers
Scala objects are initialized lazily; their top-level code will be executed once when the object is first loaded and used.
Importing a class does not cause it to be loaded, so nothing happens.
Evaluating z in the REPL causes the object's class to be loaded and the initialization code to be executed. This will only happen once, just like a static initializer in Java.
Evaluating z again in the REPL prints out the value from the previous initialization. The initialization code is not run again, so neither of the println statements is executed.
Related
How is it possible to call print() or println() without having the object on the left side? Also how are these two methods having a side effect? How would one determine if there is a side effect or not? All they do is give output to the console and not change anything from my understanding.
println() is defined in Predef.scala
The Predef object provides definitions that are accessible in all
Scala compilation units without explicit qualification.
https://www.scala-lang.org/api/current/scala/Predef$.html
To check for side effect, you'll have to see what is actually being passed to println(). Demo in the below snippet:
object Test extends App {
var x = 10
def hello(): String = "hello"
def helloWithSideEffect(): String = {
x = 11
"hello again"
}
println(x)
println(hello())
println(x)
println(helloWithSideEffect())
println(x)
}
Result
10
hello
10
hello again
11
For some reason, intermediate values aren't being printed out in the REPL console (right hand side of the worksheet)
For instance, this is what I have:
object test {
val obj = new MyObject(1)
obj.value
}
class MyObject(x: Int) {
def value = x
}
In the REPL results, I only get the following:
defined module test
.
.
.
defined class MyObject
However, I don't get any of the intermediate results, such as when I evaluate x.value
I would expect something like:
> MyObject#14254345
> 1
after x.value
Any reason why this isn't printing out?
What ended up working for me in this case (and this might be particular to IntelliJ 14, since I've seen it working the other way in Eclipse) is I added the class inside the object block, like this:
object test {
val obj = new MyObject(1)
obj.value
class MyObject(x: Int) {
def value = x
}
}
This forced the REPL instance inside the worksheet to auto-evalute the result and print them out on the right hand side.
To make it work like it does in Eclipse, turn on "eclipse compatibility" mode. This worked for me using IntelliJ IDEA 2016.
Preferences > Language & Frameworks > Scala > Worksheet
Then, check the Use "eclipse compatibility" mode checkbox.
Sorry, I don't have enough reputation to comment so I have to write it here.
If you want to get the result you want, maybe you can try like this.
scala> :paste
// Entering paste mode (ctrl-D to finish)
object test {
val obj = new MyObject(1)
println(obj.value)
}
class MyObject(x: Int) {
def value = x
}
// Exiting paste mode, now interpreting.
defined object test
defined class MyObject
scala> test.obj
1
res4: MyObject = MyObject#1cd072a9
when you paste the code, test and MyObject are not initialized, certainly you can not get any print.
test.obj will cause test to be initialized so will obj, meantime, obj.value also get evaluated. However, if you don't something about it(like print), it's just a pure expression.
I want to write a simple Scala script that runs some methods that are defined in another file.
Each line that runs this method requires information that won't be available until runtime. For simplicity sakes, I want to abstract that portion out.
Thus, I want to use Currying to get the result of each line in the script, then run the result again with the extra data.
object TestUtil {
// "control" is not known until runtime
def someTestMethod(x: Int, y: Int)(control: Boolean): Boolean = {
if (control) {
assert(x == y)
x == y
} else {
assert(x > y)
x > y
}
}
}
someTestMethod is defined in my primary codebase.
// testScript.sc
import <whateverpath>.TestUtil
TestUtil.someTestMethod(2,1)
TestUtil.someTestMethod(5,5)
Each line should return a function, that I need to rerun with a Boolean.
val control: Boolean = true
List[(Boolean) -> Boolean) testFuncs = runFile("testScript.sc")
testFuncs.foreach(_(control)) // Run all the functions that testScripts defined
(Sorry if this is a weird example, it's the simplest thing I can think of)
So far I have figured out how to parse the script, and get the Tree. However at that point I can't figure out how to execute each individual tree object and get the result. This is basically where I'm stuck!
val settings = new scala.tools.nsc.GenericRunnerSettings(println)
settings.usejavacp.value = true
settings.nc.value = true
val interpreter: IMain = new IMain(settings)
val treeResult: Option[List[Tree]] = interpreter.parse(
"""true
| 5+14""".stripMargin)
treeResult.get.foreach((tree: Tree) => println(tree))
the result of which is
true
5.$plus(14)
where 5 + 14 has not been evaluated, and I can't figure out how, or if this is even a worthwhile route to pursure
In the worst case you could toString your modified tree and then call interpreter.interpret:
val results = treeResult.get.map { tree: Tree => interpreter.interpret(tree.toString) }
It seems like it would be better to have the other file evaluate to something that can then be interpreted passing control (e.g. using the scalaz Reader Monad and for/yield syntax). But I assume you have good reasons for wanting to do this via an extra scala interpreter.
Is it possible to configure a Scala interpreter (tools.nsc.IMain) so that it "forgets" the previously executed code, whenever I run the next interpret() call?
Normally when it compiles the sources, it wraps them in nested objects, so all the previously defined variables, functions and bindings are available.
It would suffice to not generate the nested objects (or to throw them away), although I would prefer a solution which would even remove the previously compiled classes from the class loader again.
Is there a setting, or a method, or something I can overwrite, or an alternative to IMain that would accomplish this? I need to be able to still access the resulting objects / classes from the host VM.
Basically I want to isolate subsequent interpret() calls without something as heavy weight as creating a new IMain for each iteration.
Here is one possible answer. Basically there is method reset() which calls the following things (mostly private, so either you buy the whole package or not):
clearExecutionWrapper()
resetClassLoader()
resetAllCreators()
prevRequests.clear()
referencedNameMap.clear()
definedNameMap.clear()
virtualDirectory.clear()
In my case, I am using a custom execution wrapper, so that needs to be set up again, and also imports are handled through a regular interpret cycle, so either add them again, or—better—just prepend them with the execution wrapper.
I would like to keep my bindings, they are also gone:
import tools.nsc._
import interpreter.IMain
object Test {
private final class Intp(cset: nsc.Settings)
extends IMain(cset, new NewLinePrintWriter(new ConsoleWriter, autoFlush = true)) {
override protected def parentClassLoader = Test.getClass.getClassLoader
}
object Foo {
def bar() { println("BAR" )}
}
def run() {
val cset = new nsc.Settings()
cset.classpath.value += java.io.File.pathSeparator + sys.props("java.class.path")
val i = new Intp(cset)
i.initializeSynchronous()
i.bind[Foo.type]("foo", Foo)
val res0 = i.interpret("foo.bar(); val x = 33")
println(s"res0: $res0")
i.reset()
val res1 = i.interpret("println(x)")
println(s"res1: $res1")
i.reset()
val res2 = i.interpret("foo.bar()")
println(s"res2: $res2")
}
}
This will find Foo in the first iteration, correctly forget x in the second iteration, but then in the third iteration, it can be seen that the foo binding is also lost:
foo: Test.Foo.type = Test$Foo$#8bf223
BAR
x: Int = 33
res0: Success
<console>:8: error: not found: value x
println(x)
^
res1: Error
<console>:8: error: not found: value foo
foo.bar()
^
res2: Error
The following seems to be fine:
for(j <- 0 until 3) {
val user = "foo.bar()"
val synth = """import Test.{Foo => foo}
""".stripMargin + user
val res = i.interpret(synth)
println(s"res$j: $res")
i.reset()
}
Looking through the Scala 2.8 Predef class, I find that there is a method "locally". As near as I can tell, it's the same as Predef.identity, except for having the "#inline" annotation. What's it for, and why is it important enough to be in Predef (and thus usable anywhere in Scala)?
It is discussed here: http://www.scala-lang.org/node/3594
The idea was to avoid the programmer error of confusing a 'dangling' local block with the template of an object/class/trait.
object test {
object a
{
val x = 1
}
object b
{ // oops, extra newline disassociates this block with the object b
val x = 1
}
}
test.a.x
//test.b.x // doesn't compile
If the programmer really wants that block to stand alone, locally could be used:
object test {
object a
{
val x = 1
}
object b
locally {
val x = 1
}
}
This thread also suggested that the first code would produce a deprecation warning. This has not yet been added.