J'ai essayé de générer une compilation SBT pour un projet open source que je voudrais référencer dans mon projet, et je suis tombé sur ce qui semblait être un bug de compilateur.Solution de contournement pour un bogue scala.language.dynamics dans le compilateur scala 2.10
Le code suivant compile, et fonctionne comme prévu en ide scala eclipse /, mais le compilateur scala 2.10.6 est incapable de digérer:
package foo
import scala.language.dynamics
object Caller extends App {
val client = new Client() // initialise an R interpreter
client.x = 1.0
}
class Client extends Dynamic {
var map = Map.empty[String, Any]
def selectDynamic(name: String) = map get name getOrElse sys.error("field not found")
def updateDynamic(name: String)(value: Any) { map += name -> value }
}
Voici mon build.sbt:
scalaVersion := "2.10.6"
libraryDependencies++= Seq(
"org.scalanlp" %% "breeze" % "0.12"
)
Quand je précise scalaVersion: = 2.10.6, je reçois l'erreur de compilation suivante:
[error] /home/philwalk/dynsbt/src/main/scala/foo/Caller.scala:8: type mismatch;
[error] found : foo.Caller.client.type (with underlying type foo.Client)
[error] required: ?{def x: ?}
[error] Note that implicit conversions are not applicable because they are ambiguous:
[error] both method any2Ensuring in object Predef of type [A](x: A)Ensuring[A]
[error] and method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A]
[error] are possible conversion functions from foo.Caller.client.type to ?{def x: ?}
[error] client.x = Seq("a","b","c")
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 3 s, completed May 3, 2016 11:03:08 AM
Avec s calaVersion: = 2.11.8, pas de problème, bien que j'ai besoin de cross-compiler, donc ce n'est pas une solution de rechange.
Un autre indice est que je peux cacher le problème en changeant cette ligne de code:
client.x = 1.0
à ceci:
client.xx = 1.0
Je vois aussi le problème quand je compile directement avec scalac 2.10. 6. Pour contourner le problème, je pourrais refactoriser le projet afin d'utiliser des noms de champs plus longs qu'un seul caractère, bien que ce ne soit pas mon projet, je suis quelque peu limité sur ce que je peux accepter comme solution de contournement. En outre, il s'agit d'un projet breeze.linalg et il serait très difficile de ne pas autoriser les noms de matrice et de vecteur à caractère unique.
Il a fallu quelques heures pour réduire le problème à ce fragment de code d'un projet plus important, et je préférerais ne pas imposer de limitations sur la version scala 2.10 de cette bibliothèque open source. Puisque ce bug semble avoir été corrigé dans la version 2.11, je suppose qu'il a été décidé de ne pas rétrograder le correctif à 2.10.
J'ai changé le titre pour refléter l'existence d'une solution de contournement (nom de champ plus long).
Avez-vous l'erreur si vous exécutez propre et ensuite compiler? – Martin
oui, c'est assez stable et répétable. Aussi facile à dupliquer, il suffit de coller le code source ci-dessus dans un fichier situé dans src/main/scala/foo/Client.scala, puis d'essayer de compiler avec sbt 0.13.11 (il sera par défaut à scala 2.10). 6, comme cela arrive). – philwalk
J'ai essayé d'exécuter directement scalac 2.10.6, et j'ai la même erreur, donc je suppose que ce n'est pas la faute de sbt. Dans sbt, lancez 'compile', puis' last' pour obtenir les paramètres exacts donnés à scalac. Edit: Même dans la variable REPL, vous n'avez pas besoin de la dépendance de la bibliothèque btw. – Martin