( ꒪⌓꒪) ゆるよろ日記

( ゚∀゚)o彡°オパーイ!オパーイ! ( ;゚皿゚)ノシΣ フィンギィィーーッ!!!

Scala2.10に文字列中の\{ _ } で式展開する機能が入るかも?

以下の記事で紹介されているが、Scala2.10の実験的な機能として、 このコミットにより、 文字列中の式展開が入るかもしれない。


Algorithmically challenged: String Interpolation on 2.10?


式展開とは、Rubyでは"foo #{hogehoge}"のように文字列中に式を埋め込んで評価した結果を元に文字列を作成すること。2.10のnightly buildを持ってきて、-Xexperimentalオプションを付けて起動すると、試してみることができる。

ozaki@mbp-4 $ scala -Xexperimental
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
Welcome to Scala version 2.10.0.r25825-b20111013020230 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val x = 1.1
x: Double = 1.1

scala> println("We have a \{ x ;2.2f}% chance of success")
We have a 1.10% chance of success

scala> "the random value is \{ util.Random.nextInt }!!"
res2: String = the random value is 289196571!!


上記のように、sprintfのオプションを合わせて指定してフォーマットを整えることができるようだ。
他にも、 このGistで紹介されているように、無名関数リテラルのように扱うこともできる。

scala> val f = "Value of \{ _ : String} is \{ _ : Int }"
f: (String, Int) => String = <function2>

scala>  f("foo", 23)
res1: String = Value of foo is 23

scala> val g : (String, Int) => String = "Value of \{ _ } is \{ _ }" // Types can be inferred
g: (String, Int) => String = <function2>

scala>  g("bar", 13)
res2: String = Value of bar is 13

scala> def show[T](t : T)(f : T => String) = f(t)
show: [T](t: T)(f: T => String)String

scala> show(23)("> \{ _ } <")        // Hole inferred as Int
res3: String = > 23 <

scala> show("wibble")("> \{ _ } <")  // Hole inferred as String
res4: String = > wibble <


ただし、現時点では残念ながらヒアドキュメント中の式展開には対応していない。

scala> """
     | ( ゚∀゚)o彡°おっぱい!おっぱい! \{ util.Random.nextInt }
     | """
res7: String = 
"
( ゚∀゚)o彡°おっぱい!おっぱい! \{ util.Random.nextInt }
"

src/compiler/scala/tools/nsc/ast/parser/Scanners.scala のprivate def getMultiLineStringLit()をいじれば対応できそうだけど……。