How does 'self' work in Scala actors?
The following code snippet is taken from Programming in Scala
import actors.Actor
object NameResolver extends Actor {
import java.net.{InetAddress, UnknownHostException}
def act() {
react {
case (name: String, actor: Actor) =>
actor ! getIp(name)
act()
case "EXIT" =>
println("Name resolver exiting.")
// quit
case msg =>
println("Unhandled message: " + msg)
act()
}
}
def getIp(name: String): Option[InetAddress] = {
try {
Some(InetAddress.getByName(name))
} catch {
case _: UnknownHostException => None
}
}
}
Firstly within react {} what does the recursive call to act() do? It looks like all the cases would fail and it will simply drop through to the end doing nothing.
Secondly in the book, they use the following REPL example
Na开发者_StackOverflowmeResolver ! ("www.scala-lang.org", self)
Where does 'self' come from? I have tried to replicate this in a main method
def main(args: Array[String]) {
NameResolver.start()
NameResolver ! ("www.scala-lang.org", Actor.self)
}
The above does not work
act()runs recursively, unless you send anEXITmessage. For any other message that neither matchEXITnor(name: String, actor: Actor),case msgwill be used. In other wordscase msgis a kind of a generic handler that processes all the unmatched messages.Actor.selfis a reliable way to refer to the actor instance from within an actor's body (it's recommended to useselfinstead ofthis, to refer to the right instance). In your case, you're callingActor.selfnot from an actor, and, thus, it fails.
The code inside
reactis called only when a new message is available. Thus, if you call recursivelyact()inside acaseclause, the actor will "wait" until a new message is sent (without blocking a thread). It's an alternative toloopwhen you want to change the behavior of the actor according to what it received. Here you stop waiting for messages when you get"EXIT".selfis supposed to be used inside an actor everytime you want to usethis.
加载中,请稍侯......
精彩评论