Не могу объяснить поведение примеров, выполненных в оболочке scala - PullRequest
4 голосов
/ 14 декабря 2011

1001 * Л.С. *

Я только изучаю Scala, используя "Программирование в Scala" Одерского и др.

В главе об актерах я столкнулся с поведением, которое не могу объяснить. Более конкретно, при попытке отправить сообщение «себе» (см. Также пример )

Вход в оболочку Scala:

scala> import scala.actors.Actor._  
import scala.actors.Actor._
scala > self ! "Hello"

scala > self.receive { case x => x }

Но последняя строка не «возвращается» с ожидаемым ответом:

resX:Any = hello

При необходимости сделать Ctrl-C, чтобы вернуть оболочку, принимающую мой ввод, и вернуть сообщение, которое:

Execution interrupted by signal.

scala> self.receive {case x => x}
// She's gone rogue, captain! Have to take her out!
// Calling Thread.stop on runaway Thread[Thread-54,5,main] with offending code:
// scala> self.receive {case x => x}

Но на самом деле работает следующее:

self ! "Hello" ; self.receive { case x => x }

Мои вопросы:

Что происходит? Почему первый пример не работает, а второй работает?!? Я хотел бы немного лучше понять поведение оболочки, так как авторы книги утверждают, что использование self в качестве получателя ответов от актеров является хорошей техникой отладки.

1 Ответ

9 голосов
/ 14 декабря 2011

В то время, когда книга была написана, был только один вид актеров: основанные на потоках актеры.Таким образом, если self был вызван для различных объектов из одного потока, он вернул тот же Actor.Начиная с Scala 2.8 (я думаю) это больше не выполняется.

Способ работы оболочки заключается в создании анонимных классов для каждого отправленного ввода, поэтому в первом случае у вас есть

object $1 {
  self ! "Hello"
}

object $2 {
  self.receive { case x => x }
}

и $1.self отличается от $2.self, а во втором случае у вас есть

object $3 {
  self ! "Hello" ; self.receive { case x => x }
}
...