Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning about reflective access of structural type member in Scala

Tags:

scala

What does this warning mean:

reflective access of structural type member method getMap should be enabled

The warning includes a reference to the scala docs but I don't understand how my code is related to the explanation. (Specifically the explanation mentions reflection... how is my code using reflection?)

I have this: (Scala 2.11.2)

object getMap {
    implicit def fromOptionToConvertedVal[T](o:Option[T]) = new {
        def getMap[R] (doWithSomeVal:(T) => R) = new {
            def orElse(handleNone: => R) = o match {
                case Some(value) => doWithSomeVal(value)
                case None => handleNone
            }
        }
    }   
}

import getMap._
val i:Option[Int] = Some(5)
val x = i getMap (_*2) orElse 1

This generates the warning below:

[warn] /Users/Greg/git/Favorites-Demo/src/main/scala/com/rs/server/ThriftServer.scala:34: reflective access of structural type member method getMap should be enabled
[warn] by making the implicit value scala.language.reflectiveCalls visible.
[warn] This can be achieved by adding the import clause 'import scala.language.reflectiveCalls'
[warn] or by setting the compiler option -language:reflectiveCalls.
[warn] See the Scala docs for value scala.language.reflectiveCalls for a discussion
[warn] why the feature should be explicitly enabled.
[warn] val x = i getMap (_*2) orElse 1
[warn]           ^
[warn] /Users/Greg/git/Favorites-Demo/src/main/scala/com/rs/server/ThriftServer.scala:34: reflective access of structural type member method orElse should be enabled
[warn] by making the implicit value scala.language.reflectiveCalls visible.
[warn] val x = i getMap (_*2) orElse 1
[warn]                        ^
like image 572
Greg Avatar asked Nov 06 '14 19:11

Greg


People also ask

What is reflection in Scala?

Given a type or instance of some object at runtime , reflection is the ability to: or to access or invoke members of that object. Let’s jump in and see how to do each of the above with a few examples. As with other JVM languages, Scala’s types are erased at compile time.

How to get the symbol for a Person constructor in Scala?

The symbol for Person s constructor can be obtained using only the runtime universe ru by looking it up in the declarations of type Person. scala> val ctorm = cm.reflectConstructor (ctor) ctorm: scala.reflect.runtime.universe.

What is suspicious code in Scala?

A first category is suspicious code that is likely the result of a programming mistake: Warnings about non-exhaustive pattern matches and uncheckable type arguments are also issued by default (note that exhaustivity warnings just received a big upgrade in Scala 2.13.4 ):

What is a synthetic class in Scala?

Thus, the Scala compiler often creates synthetic classes (i.e. automatically-generated classes) that are used at runtime in place of user-defined classes. This is quite commonplace in Scala and can be observed when using Java reflection with a number of Scala features, e.g. closures, type members, type refinements, local classes, etc.


Video Answer


1 Answers

I think what's going on is that the new { ... } objects are structurally typed, which require reflection to implement.

The underlying reason is that Scala structural typing allows objects to be treated as if they are instances of many types according to which methods they actually have (like duck typing). The JVM allows exactly one type so methods that are not part of the object's underlying type have to be accessed via something other than a normal virtual method call. The mechanism that's used in this case is reflection.

When the scala compiler sees an invocation of a method that's being called on a structurally typed object it (modulo some optimizations) translates a method call like:

a.f(b, c)

to

a.getClass
    .getMethod("f", Array(classOf[B], classOf[C]))
    .invoke(a, Array(b, c))

Example taken from the place where the technique was described.

The Scala team decided to enforce an opt-in policy for advanced features. reflectiveCalls happens to be one of them as documented in this SIP

like image 102
mrmcgreg Avatar answered Oct 03 '22 02:10

mrmcgreg