2

I am new to Scala and I have setup an environment with IntelliJ. I found out one problem I could not explain, here is the code:

object HelloWorld extends App{
    print("before")
    var aMap = Map("A"->1, "B"->2)
    println("after")
    println(aMap)
}

I noticed that println(aMap) could clearly print out the Map("A"->1, "B"->2), so I want to debug and found out if Map has implemented an funcn which will be called by println, using IntelliJ. So I set a debug point on:

println(aMap)

When I "step into" the function, it seems var aMap = Map("A"->1, "B"->2) was called again! So , whats the reason that this was called a second time?

5
  • 1
    How do you know the assignment is called again? Do you see it in your stack trace? Is the memory reference of aMap changed? Commented May 28, 2014 at 13:20
  • 1
    What happens if you change var to val? Commented May 28, 2014 at 13:20
  • @Jordan Parmer Yes, I saw the call stack, when hit println(aMap) and press F7 to stepinto it, I could see on the top of call frames is the line of var aMap ..., In python, if you want to print an object, it will call the object str method, and I thought scala may have such kind of features, well, it turned out that var aMap =..this line is hit again, I don't know the reason, jdk is 17u55 scala is 2.11.0 Commented May 28, 2014 at 13:31
  • I changed to val, and seems val aMap = .. this line is hit again. I didn' mean that the assignment is called again, I just meant that using debug mode with step into, it seems that line was hit again, and I don't know the reason. Am I missing something? Commented May 28, 2014 at 13:33
  • 1
    it's still unclear what bothers you -- are you're stating that there is a variable aMap which is assigned twice, or what? if so, as Jordan said, you can check whether object reference (it looks like a hash) has changed -- this is evidence of abovementioned scenario, otherwise it's just a debugger wart, who is probably got confused with DelayedInit semantics. Commented May 28, 2014 at 13:59

1 Answer 1

3

All top level fields (var/val) are also turned into methods to help with the concept of a uniform access principle.

var map = Map(1->2)
val list = List(1,2)

becomes

var map = Map(1->2)
def map = map
def map_=(nValue: Map[Int.Int]) {map = nValue}

val list = List(1,2)
def list = list
// No setters for vals

So when you call println(aMap) it uses the hidden accessor method to get the value of aMap.

This is all happening because you are at the top-level of the object. Had this been in a method:

object HelloWorld extends App{
  def run() {
    print("before")
    var aMap = Map("A"->1, "B"->2)
    println("after")
    println(aMap)
  }
  run()
}

Then the var aMap would be a local variable and not use an indirect lookup.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.