Microsoft TranslatorをScalaから使ってみた
まずまとめ
Ruby、Go、Scalaで作ってみて、一番楽に感じたのはRubyだったかな(ほぼ生粋のPHPerなもので)。
慣れればもっといい書き方がありそう。
記述量的にはScalaが少なかったんだけど(.sbtファイルを含めると別)、一番悩んだのはScalaかも(多少なりともScalaらしい書き方をしようとしたため)。
Goはパフォーマンスは良さそうなんだけど、今回のようなループ回し続けて、時々問い合わせて出力する、という流れだと体感に大差はなさそうな気がする。
それよりも意外に簡単に書けたのが印象的でした。
追記。
Goのコンパイル速度のありがたさをScala版を作ってみて把握。
さすがにGo言語の目的の一つだなぁと。
追記終わり。
成果物のサイズは、
Scala(Translator-assembly-0.0.1.jar) => 8.65MB
Go(translator.exe) => 3.76MB
Ruby => 3.64KB (スクリプト単体なので当たり前)
でした。
以下、Scalaでの実装
src/main/scala/Translator.scala
import dispatch._, Defaults._ import scala.util.parsing.json.JSON import java.util.Date import scala.annotation.tailrec object Translator { def main(args: Array[String]) { println("input English word") println("'!' to quit") @tailrec def readToTranslate(accessTokenMessage:AccessTokenMessage):Unit = { val line = Console.readLine("from: ") line match { case "!" => () case word if word.trim.length > 0 => { val atm = AccessTokenMessage(Option(accessTokenMessage)) println("to: " + translate(word.trim, atm)) readToTranslate(atm) } case _ => { println(">> [empty]") readToTranslate(accessTokenMessage) } } } readToTranslate(AccessTokenMessage.empty) } def translate(word:String, atm:AccessTokenMessage):String = { MicrosoftTranslator.translate(word, atm.accessToken) } } object MicrosoftTranslator { def MsTransLatorPrimaryKey = "Your Primary Key" def MsTransLatorClientId = "Your Client Id" def MsTransLatorClientSecret = "Your Client Secret" def MsTransLatorUrl = "http://api.microsofttranslator.com/V2/Http.svc/Translate" def MsTransLatorScope = "http://api.microsofttranslator.com" def MsTransLatorAccessTokenUrl = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13" def MsTransLatorGrantType = "client_credentials" // Dispatch http://dispatch.databinder.net/Dispatch.html // url(MsTransLatorAccessTokenUrl)は以下のようにも書ける。 def authSecureHost = host("datamarket.accesscontrol.windows.net").secure def authSecureRequest = authSecureHost / "v2" / "OAuth2-13" // 新しいアクセストークンを取得する def newAccessTokenMessage: Map[String, String] = { val params = Map( "client_id" -> MsTransLatorClientId, "client_secret" -> MsTransLatorClientSecret, "scope" -> MsTransLatorScope, "grant_type" -> MsTransLatorGrantType ) val req = url(MsTransLatorAccessTokenUrl) << params val contents = Http(req OK as.String) val jsonResult = JSON.parseFull(contents()) jsonResult.get.asInstanceOf [Map[String, String]] } def translate(word:String, accessToken:String):String = { val headerValue = "Bearer " + accessToken val headerParams = Map("Authorization" -> headerValue) val params = Map("text" -> word, "from" -> "en", "to" -> "ja") val req = url(MsTransLatorUrl) <<? params <:< headerParams val contents = Http(req OK as.xml.Elem) contents().text } } object AccessTokenMessage { def apply(message: Option[AccessTokenMessage]):AccessTokenMessage = message match { case Some(m) if !m.timeout => m case _ => new AccessTokenMessage(MicrosoftTranslator.newAccessTokenMessage) } def empty = null } class AccessTokenMessage(message:Map[String, String]) { val createTime = System.currentTimeMillis def accessToken = message("access_token").toString def expiresIn = message("expires_in").toLong def timeout = if (createTime + expiresIn * 1000 <= System.currentTimeMillis) true else false }
build.sbt
import AssemblyKeys._ // put this at the top of the file // for assembly (jarファイルを作る) http://qiita.com/items/9d19bcf16c3729d98c1b assemblySettings //メインクラスを明示的に指定 mainClass in assembly := Some("Translator") name := "Translator" version := "0.0.1" scalaVersion := "2.10.1" libraryDependencies += "org.scalatest" % "scalatest_2.10" % "1.9.1" % "test" libraryDependencies += "org.slf4j" % "slf4j-simple" % "1.6.4" libraryDependencies ++= Seq( "net.databinder.dispatch" %% "dispatch-core" % "0.10.0" )
project/plugins.sbt
resolvers += "Sonatype snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/" // for assembly resolvers += Resolver.url("artifactory", url("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases"))(Resolver.ivyStylePatterns) addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.8.8")
あとはsbtで
compile
assembly
以下のjarファイルが作られる。
target/scala-2.10/Translator-assembly-0.0.1.jar
java -jar target/scala-2.10/Translator-assembly-0.0.1.jar
として実行。
- 作者: 小笠原啓,尾崎智仁,関隆,水島宏太,今井敬吾
- 出版社/メーカー: 秀和システム
- 発売日: 2011/06
- メディア: 単行本
- 購入: 2人 クリック: 134回
- この商品を含むブログ (20件) を見る