Map( ('memo, 'scala), ('ver, 2.81), ('lib, 'Actor), ('level, 1) )

うだうだ言ってる暇あれば手を動かすことが大事って事なので、
こちらhttp://wota.jp/ac/?date=20101014を参考にLevel50を目指した記録*1

で、まずは適当にscala実行環境つくって

$ cd sbt
$ mkdir AcotorSample
$ sbt s

で、project/build.prorertiesを編集して

$ cd project
$ diff build.properties build.properties~
7c7
< build.scala.versions=2.8.1
---
> build.scala.versions=2.7.7

で、いざ経験値稼いでレベルアップすりゅ^^

 ただサンプルをなぞるだけの簡単なお仕事w<

import scala.actors.Actor

//level.5
class Foo extends Actor {
  def act = println("hello world.5")
}

//level.26
case class Ping()
case class Pong()

object ActorsSample{
  def main(args: Array[String]) = {
    //level.8
    (new Foo).start
    
    //level.11
    import scala.actors.Actor.actor
    actor { println("hello world.11")}
    
    //level.13
    val foo = actor { }
    foo ! "hello"
    
    //level.19
    import scala.actors.Actor.receive
    val hello = actor {
      receive {
	case "hello" => println("hello world.19")
      }
    }
    hello ! "foo"
    hello ! 0
    hello ! "hello"
    
    //level.22
    hello ! "hello"
    
    // //level.23
    // import scala.actors.Actor.loop
    // val hello_loop = actor {
    //   loop {
    // 	receive {
    // 	  case "hello" => println("hello world.23")
    // 	}
    //   }
    // }
    // hello_loop ! "hello"
    // hello_loop ! "hello"

    //level.26
    import scala.actors.Actor.loop
    import scala.actors.Actor.sender
    val server = actor {
      receive { case Ping => sender ! Pong}
    }
    val watch = actor {
      server ! Ping
      receive { case Pong => println("server is alive!26")}
    }
    
    //level.27
    val res = server !? Ping
    res match {
      case Pong => println("alive!27")
      case _    => println("???")
    }
  }
}

 筈だったんだけど、Level27でプログラムが終了しなくなった>A<

> run
[info]
[info] == compile ==
[info]   Source analysis: 1 new/modified, 0 indirectly invalidated, 0 removed.
[info] Compiling main sources...
[info] Compilation successful.
[info]   Post-analysis: 15 classes.
[info] == compile ==
[info]
[info] == copy-resources ==
[info] == copy-resources ==
[info]
[info] == run ==
[info] Running ActorsSample
hello world.5
hello world.11
hello world.19
server is alive!26

 ん、Level36のデフォルトスレッド数が4個ってのに、
引っかかってるのか?

 素直にREPLでした方が早いかな。

...とか思ったけど、普通にバグってたw;

 Level27で呼ぶ先のactorのserverが無かったね。
ので、server2で作成。

    //level.26
    import scala.actors.Actor.loop
    import scala.actors.Actor.sender
    val server1 = actor {
      receive { case Ping => sender ! Pong}
    }
    val watch = actor {
      server1 ! Ping
      receive { case Pong => println("server is alive!26")}
    }

    //level.27
    val server2 = actor {
      receive { case Ping => sender ! Pong}
    }
    val res = server2 !? Ping
    res match {
      case Pong => println("alive!27")
      case _    => println("???")
    }

でも、なんかserver1とかserver2が悲しいので修正。

import scala.actors.Actor

//level.26
case class Ping()
case class Pong()
case class Exit()

//level.33
import scala.actors.Actor.react
import scala.actors.Actor.sender
class Server extends Actor{
  def act{ 
    react {
      case Exit => exit
      case Ping => sender ! Pong
      act
    }
  }
}

//level.39
import scala.actors.{ Actor,TIMEOUT}
class RunLater(sec:Int, code: =>Unit) extends Actor{
  def act = reactWithin(sec*1000){ case TIMEOUT => code}
}

class Monta extends Actor{
  def later(sec: Int)(code: =>Unit) = new RunLater(sec, code).start
  def act{
    react{
      case "EXIT" => exit
      case "FA" => {
        println("...")
        later(3){ println("timeout.39")}
        act
      }
    }
  }
  start()
}

object ActorsSample{
  def main(args: Array[String]) = {
    //level.26
    import scala.actors.Actor.loop
    val server = (new Server).start
    val watch = actor {
      server ! Ping
      receive { case Pong => println("server is alive!26")}
    }
    
   //level.27
    (server !? Ping) match {
      case Pong => println("alive!27")
      case _    => println("???")
    }
    
    //level.29
    actor {
      (server !? Ping) match {
        case Pong => println("alive!29")
      }
    }
    server !! (Ping, { case Pong => println("alive!29") })
    
    //level.39
    val mino = new Monta
    mino ! "FA"

    server ! Exit
    mino ! "EXIT"
  }
}

書き写すだけの簡単なお仕事でしたねw;

 これで、Level50って事は魔王を倒せるの(# ゚Д゚)?

*1:scalaのレベルも酷いかもw;