简体   繁体   中英

Debugging scala code with recursive function in Intellij Idea

I have a trivial class named RecursiveTraversable :

class RecursiveTraversable extends Traversable[Any]{
  override def foreach[U](f: (Any) => U): Unit = {
    recursivePrint(1)
  }

  @tailrec
  private def recursivePrint(counter: Long): Unit = {
    println(s"Test $counter...")
    recursivePrint(counter+1)
  }
}

and a trivial Main object:

object Main {
  def main (args: Array[String]) {
    new RecursiveTraversable().foreach(_ => None)
  }
}

To debug this code I've set a breakpoint at println(s"Test $counter...") in RecursiveTraversable but debugger doesn't stop at this point. I can see stdout counting and this at debug panel is "Collecting data...".

Any thoughts on what am I doing wrong and how can I debug this kind of code?

This is a tricky one. The reason is that the Debugger prints a String representation of the enclosing object when you stop. In the case of Traversable , it relies on foreach , thereby you get an infinite loop when the Debugger tries to create that string representation.

The solution requires two steps. First, you override toString :

class RecursiveTraversable extends Traversable[Any] {
  def foreach[U](f: Any => U): Unit =
    recursivePrint(1)

  override def toString = "Disabled"  // !

  def recursivePrint(counter: Long): Unit = {
    println(s"Test $counter...")
    recursivePrint(counter + 1)
  }
}

object Main {
  def main (args: Array[String]): Unit =
    new RecursiveTraversable().foreach(_ => ())
}

Second you disable "Friendly display of Scala collections in debugger" in Settings > Debugger, as that bypasses toString .

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM