カスタム補間子で自分用のString interpolationを作る

scalaでは s"" という形式で文字に変数を直接埋め込むことができます。

val a = "つ"
val b = "ら"
val c = "い"
s"very $a $b $c poyo."

でscalikejdbcには sql"" とかもあり、そもそもscala的には s"" も構文的に特別扱いされているわけではなくて 自分で簡単にオリジナルのものを作れるよということを教わったので試してみました。

公式機能なのでしっかり公式ドキュメントにもしっかりありました。

文字列の補間 - Scala Documentation

つらぽよ文字列

ということで tsurai"" とかくと変数の間に(´・_・`)やら(◞‸◟)が埋め込まれるような補間子を作ってみます。

implicit class TsuraiHelper(val sc: StringContext) extends AnyVal {
  def tsurai(args: Any*): String = {
    val strings = sc.parts.iterator
    val expressions = args.iterator
    var buf = new StringBuffer(strings.next)
    while(strings.hasNext) {
      buf append "(´・_・`)"
      buf append expressions.next
      buf append "(◞‸◟)"
      buf append strings.next
    }
    buf.toString
  }
}

REPLで実行すると以下のようになります。

scala> :paste
// Entering paste mode (ctrl-D to finish)

implicit class TsuraiHelper(val sc: StringContext) extends AnyVal {
  def tsurai(args: Any*): String = {
    val strings = sc.parts.iterator
    val expressions = args.iterator
    var buf = new StringBuffer(strings.next)
    while(strings.hasNext) {
      buf append "(´・_・`)"
      buf append expressions.next
      buf append "(◞‸◟)"
      buf append strings.next
    }
    buf.toString
  }
}

// Exiting paste mode, now interpreting.

defined class TsuraiHelper

scala> val a = "つ"
a: String = つ

scala> val b = "ら"
b: String = ら

scala> val c = "い"
c: String = い

scala> tsurai"very $a $b $c poyo"
res3: String = very (´・_・`)つ(◞‸◟) (´・_・`)ら(◞‸◟) (´・_・`)い(◞‸◟) poyo

つらそうですね(´・_・`)

もちろん def tsurai の中では何でも出来るのでSQLのプリペアードステートメントを用意してから変数をbindしたりすることもできます。 sql"" を使わないと ? などでプレースホルダーを表し、別の引数で変数を渡す必要がありますが、引数と?の数と順番の対応がとれている必要があるなど少し面倒です。 sql"" を使うとそういった面倒な手順を踏まずに安全なSQLを組み立てることができるので安全かつ便利ということらしいです。