これはScala Advent Calendar 2015(Adventar版)10日目です。9日目はShinpeimさんの既存のクラスをScalazで定義されている型クラスのインスタンスにするの巻でした。
さて、ScalaでLuaです。みんなScala上でLua動かしたいですよね!?1
libraryDependencies += "org.luaj" % "luaj-jse" % "3.0.1"
ただ実行するだけならJsePlatform.standardGlobals().load
を使います。またloadFile
メソッドでファイルも指定できるようです。
import org.luaj.vm2.lib.jse._
val globals = JsePlatform.standardGlobals()
val chunk = globals.load("print 'hello, world'")
chunk.call
$ sbt run
[info] Set current project to (...)
[info] Compiling 1 Scala source to ...
[info] Running Main
hello, world
ScalaからLuaに値を渡したり、逆にLuaから値を受けとりたくなりますよね。もちろん可能です。
import javax.script.ScriptEngineManager
val manager = new ScriptEngineManager()
val engine = manager.getEngineByName("luaj")
engine.put("x", 10)
engine.put("y", 20)
engine.eval("z = x + y")
val result = engine.get("z")
println(result) // => 30
調子に乗ってLuaスクリプトを非同期で実行してみました。
import javax.script.ScriptEngineManager
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
object Main {
def executeLua[T](script: String, returnVariable: String, binds: Map[String, Any]): Future[T] = Future {
val manager = new ScriptEngineManager()
val engine = manager.getEngineByName("luaj")
binds.foreach { bind =>
engine.put(bind._1, bind._2)
}
engine.eval(script)
engine.get(returnVariable).asInstanceOf[T]
}
def main(args: Array[String]): Unit = {
val luaScript =
"""
|function fib(n)
| if n < 2 then return n end
| return fib(n - 2) + fib(n - 1)
|end
|
|result = fib(x)
""".stripMargin
val f1 = executeLua[Int](luaScript, "result", Map("x" -> 10))
val f2 = executeLua[Int](luaScript, "result", Map("x" -> 38))
val f3 = executeLua[Int](luaScript, "result", Map("x" -> 10))
f1.onSuccess { case r: Int => println(r) }
f2.onSuccess { case r: Int => println(r) }
f3.onSuccess { case r: Int => println(r) }
Await.ready(f1, Duration.Inf)
Await.ready(f2, Duration.Inf)
Await.ready(f3, Duration.Inf)
}
}
$ ./sbt run
[info] Set current project to (...)
[info] Compiling 1 Scala source to ...
[info] Running Main
55
55
39088169
[success] Total time: 26 s, completed 2015/12/09 3:14:23