Как заставить актера отправлять сообщения обратно вызывающей стороне? - PullRequest
1 голос
/ 23 июня 2011

Я пытаюсь воспроизвести этот пример . Все компилируется, но когда я запускаю его, все мои результаты выглядят так:

  scala> NameResolver ! ("www.scala-lang.org", self)

  scala> self.receiveWithin(0) { case x => x }
  res0: Any = TIMEOUT // and not Some(www.scala-lang.org/128.178.154.102)

  scala> NameResolver ! ("wwwwww.scala-lang.org", self)

  scala> self.receiveWithin(0) { case x => x }
  res1: Any = TIMEOUT // and not None

Вот мой пример:

import scala.actors._
import scala.actors.Actor._

case class Plus(x: Int, y: Int)

val concurrentCalculator = actor {
   while(true)
      receive {
         case Plus(x, y) => println(x + y)
         case (Plus(x, y), caller: Actor) => caller ! (x + y)
      }
}

scala> concurrentCalculator ! Plus(2,3)
5

scala> concurrentCalculator ! (Plus(2,3), self)

scala> self.receiveWithin(1000) { case x => x }
res0: Any = TIMEOUT // WTF?

Так почему я получаю TIMEOUT вместо действительного результата?

Ответы [ 2 ]

4 голосов
/ 23 июня 2011

Вы можете проверить, что self возвращает разные значения для разных вызовов, не входящих в кодовый блок, благодаря тому, как работает Scala REPL (каждое вычисляемое выражение компилируется в отдельный класс):

scala> self
res3: scala.actors.Actor = scala.actors.ActorProxy@1bb0ff0

scala> self
res4: scala.actors.Actor = scala.actors.ActorProxy@46530

В одном блоке кода он будет работать, даже если он явно не объявлен как актер:

scala> {
     | concurrentCalculator ! (Plus(2,3), self)
     | self.receiveWithin(1000) { case x => x }
     | }
res9: Any = 5
0 голосов
/ 23 июня 2011

Проблема здесь в том, что вызывающий код не является актером, поэтому второй случай в вашем concurrentCalculator актере не совпадает.

Попробуйте вместо этого, и вы должны увидеть, что вы ожидаете:

val me = actor { 
  concurrentCalculator ! (Plus(2,3), self); 
  self.receiveWithin(1000) { case x => println(x) } 
}
...