Intellij ideaとSBTでデバッグするメモ

Intellij ideaでscalaとSBTを使ってデバッグするメモ

OSはScientific linux 6.2、Intellij idea 12の場合です。

  • IntellijのSBT Integrationを使いたい場合

f:id:lambda_night:20130628112505p:plain

Settings->SBT->IDESettingsの、
VM parametersに対して

-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=127.0.0.1:5005

を追記。
SBT launcherは環境に応じて適宜設定。

  • 普通にターミナルからSBTを使いたい場合

/usr/bin/sbtを開いて

declare -r default_sbt_opts="-XX:+CMSClassUnloadingEnabled"

となっているところを

declare -r default_sbt_opts="-XX:+CMSClassUnloadingEnabled -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=127.0.0.1:5005"

に変更。

  • デバッガ接続設定

上記のどちらかを設定した後、IntelliJのRunメニューからEditConfigurationを選択。
緑の+をクリックしてRemoteを選択。

f:id:lambda_night:20130628113225p:plain

デフォルトで127.0.0.1:5005に接続するようになっています。

後はそのままいじらずにOK押して閉じます。

  • 実際につないでみる

SBTを起動してみましょう。以下の様な表示がでるはずです。

$ sbt
Detected sbt version 0.12.2
Starting sbt: invoke with -help for other options
Listening for transport dt_socket at address: 5005
[info] Loading project definition from /home/xxx/project
[info] Set current project to someproject (in build file:/home/xxx/ideaprojects/project/)

Listening for transport dt_socket at address: 5005

に着目しましょう。これでデバッガ接続を待ち受ける様になりました。

あとは先ほど作ったRemoteデバッグ設定をデバッグモードで起動して、REPLとかで実行してみましょう。
いつもどおりにデバッグできるはずです。

String Interpolationを活用してみた

ScalaにはString Interpolationという機能があって、簡素な記法で文字列に変数を埋め込めます。

文字列リテラルの頭に「s」をつけて使います。

例えばこんなふうに使えます。

scala> val weather: String = "晴れ"
weather: String = 晴れ
scala> println(s"今日は $weather だったよ。")
今日は 晴れ だったよ。

多項式でもOK

scala> println(s"1 + 2 = ${ 1 + 2 }")
1 + 2 = 3

更に自分で「s」に当たるものを定義することもできます。

   implicit class WeatherHelper(sc: StringContext) {
    def weather(args: Any*): String = {
      val str = sc.parts.mkString
      s"今日の天気は ${str} ですよ"
    }
  }

こんなふうにStringContextからのImplicit conversionを書きましょう。

scala> weather"曇り"
res3: String = 今日の天気は 曇り ですよ


こんな具合です。内側に書いた変数はargsに、文字列そのものはStringContext#partsに入っています。


この仕組みを上手く活用したライブラリとして、ScalikeJDBCがあります

https://github.com/seratch/scalikejdbc

sql"select * from users where id = ${id}").map(*).single.apply() 

このようにクエリを組み立て&実行出来ます。埋め込んだ変数はしっかりサニタイズされてるので、インジェクション対策もばっちり。

String interpolationをうまく活用したいですね。