tags:

views:

84

answers:

2

I have the following code. If I comment the call to "foo()" inside the actor's body, the code works fine. But if "foo()" is activated... my code freezes!

Anyone kwnows why?

import scala.actors.Actor._

object Main extends Application{
    def foo() = {
     println("I'm on foo")
    }

    def testActor() = {
     val target = self

     for(i <- 1 to 100){
      actor{
       foo()
       target ! i
      }
     }

     var total = 0
     receive{
      case x:Int => total += x
     }
     total
    }

    println("Result: " + testActor())
}
+2  A: 

The Application trait and its use is at fault here. When you have code running within the body of a Application rather than within a main method, that code is actually running as part of the constructor. So at the point where you call the testActor() method, the object hasn't actually finished initialising.

To fix it, move the println line into a main method:

def main (args: Array[String]) {
    println("Result: " + testActor())
}

Because this problem happens so easily, the Application trait is considered to be bad news.

Marcus Downing
As mentioned here: http://stackoverflow.com/questions/1332574/common-programming-mistakes-for-scala-developers-to-avoid/1334962#1334962
Daniel
+2  A: 

"testActor" is called while the "Main" class is initializing. The actor code is executing in a different thread(not the main thread) and it's blocked and can not send any message because it's trying to access a method in a class (Main in this case) that is being initialized in the main thread. "receive" hangs because it can not receive any message.

Do not use "extends Application". Use "def main(args: Array[String])" and save yourself a lot of trouble.

See http://scala-blogs.org/2008/07/application-trait-considered-harmful.html

Walter Chang