1

I was playing around in the Play Framework's Scala console, and it looks like it's somehow doing implicit conversions without having any implicit defs in scope:

scala> import play.api.libs.json._
import play.api.libs.json._

scala> :implicits
No implicits have been imported other than those in Predef.

scala> Json.arr _
res0: Seq[play.api.libs.json.Json.JsValueWrapper] => play.api.libs.json.JsArray = <function1>

scala> Json.arr(1,2,3)
res1: play.api.libs.json.JsArray = [1,2,3]

As you can see, the output of :implicits shows that the only implicit conversions in scope are those from scala.Predef. However, somehow my Int values (1,2,3) are being converted to play.api.libs.json.Json.JsValueWrapper instances when I pass them to Json.arr().

I was under the impression that implicit conversions were only applied when the implicit conversion was in scope (i.e., it was declared or imported in the current scope). How then is this conversion happening?


Update: I think the Play console must be doing something because the conversion happens even if I open a fresh console and make a simple assignment (no imports at all):

scala> val x: play.api.libs.json.Json.JsValueWrapper = 1
x: play.api.libs.json.Json.JsValueWrapper = JsValueWrapperImpl(1)
DaoWen
  • 31,184
  • 6
  • 65
  • 95

1 Answers1

4

It looks like this is the conversion: https://github.com/playframework/playframework/blob/eeb155f39d1394ac4fa9a5f6316a9fe0884582b0/framework/src/play-json/src/main/scala/play/api/libs/json/Json.scala#L118

I believe it's being found in the explicit scope of the argument's type, as described in this answer about where implicits come from: Where does Scala look for implicits?

Community
  • 1
  • 1
  • I have *Programming in Scala, 2nd Ed.* (which I've read all the way through), but it was written for Scala 2.8, and according to the answer you link to the argument type scope thing was added in 2.9. That explains why I couldn't figure out where it's coming from, and why it wasn't showing up in the `:implicits` list. Thanks! I should probably just go read through the language spec one of these days... – DaoWen Sep 18 '13 at 06:17
  • I don't think it's incorrect--the compiler's looking in the implicit scope of the type JsValueWrapper and finding the conversion I linked – Kelsey Gilmore-Innis Sep 18 '13 at 18:17
  • 1
    @KelseyGilmore-Innis - I agree (hence my accepting your answer). I have no idea what som-snytt is talking about. – DaoWen Sep 18 '13 at 19:13