user79074
user79074

Reputation: 5300

Can implicit class also be Dynamic?

I tried to add dynamic functionality to a class implicitly by doing the following:

case class C(map: Map[String, String])

implicit class Enhancer(c: C) extends Dynamic {
    def selectDynamic(str: String) = c.map.getOrElse(str, "")
}

val c = C(Map("a" -> "A"))

And this will not compile

val up = c.a

But an explicit call will:

val up = Enhancer(c).a

Why is this?

Upvotes: 4

Views: 176

Answers (2)

jwvh
jwvh

Reputation: 51271

Yes, this will compile...

val up = Enhancer(c).a  //up: String = A

...but then, so will this...

val up = Enhancer(c).wxyz  //up: String = ""

If class C doesn't have a member a, and class Enhancer doesn't have a member a, the compiler isn't going to check if a is supported dynamically because everything is supported dynamically.

If I were designing a language/compiler, and it came to a choice between allowing a.anything (because Enhancer is Dynamic), or allowing only natively supported members (ignoring dynamics), I think I'd go with the latter.

Upvotes: 2

Alexey Romanov
Alexey Romanov

Reputation: 170919

The rule in the specification is

Selection on Dynamic

If none of the previous conversions applies, and e is a prefix of a selection e.x, and e's type conforms to class scala.Dynamic, then the selection is rewritten according to the rules for dynamic member selection.

Conformance doesn't include "can be implicitly converted"; so no, you can't add Dynamic implicitly. You could propose it for some future version of Scala, but I would be surprised if it's accepted.

Upvotes: 2

Related Questions