que tienen una sencilla aplicación: (. El t2mapper
es de this answer)¿Por qué este código de Scala arroja IllegalAccessError en tiempo de ejecución?
object Test extends App {
implicit def t2mapper[X, X0 <: X, X1 <: X](t: (X0, X1)) = new {
def map[R](f: X => R) = (f(t._1), f(t._2))
}
println("Hello!")
val (foo, bar) = (1, 2) map (_ * 2)
println((foo, bar))
}
El código compila bien:
$ scalac -version
Scala compiler version 2.9.1 -- Copyright 2002-2011, LAMP/EPFL
$ scalac -unchecked Test.scala
$
pero cuando es ejecutado, se lanza una IllegalAccessError
(antesHello!
que se imprime):
$ java -version java version "1.6.0_24" OpenJDK Runtime Environment (IcedTea6 1.11.1) (6b24-1.11.1-4ubuntu3) OpenJDK Server VM (build 20.0-b12, mixed mode) $ scala Test java.lang.IllegalAccessError: tried to access field Test$.reflParams$Cache1 from class Test$delayedInit$body at Test$delayedInit$body.(Test.scala:6) at Test$.(Test.scala:1) at Test$.(Test.scala) at Test.main(Test.scala) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:616) at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78) at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24) at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88) at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78) at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101) at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33) at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40) at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:56) at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80) at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89) at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Tenga en cuenta que con las dos últimas líneas reemplazados por
println((1, 2) map (_ * 2))
o
val (foo, bar) = (2, 4)
println((foo, bar))
o
val intermediate = (1, 2) map (_ * 2)
val (foo, bar) = intermediate
println((foo, bar))
imprime (2,4)
como se esperaba. Pero cuando se envuelve en un bloque
{
val intermediate = (1, 2) map (_ * 2)
val (foo, bar) = intermediate
println((foo, bar))
}
o
private val blah = {
val intermediate = (1, 2) map (_ * 2)
val (foo, bar) = intermediate
println((foo, bar))
}
se produce la excepción.
¿Por qué la primera y última forma provoque una JVM para lanzar un error en tiempo de ejecución?
He informado esto como un problema en https://issues.scala-lang.org/browse/SI-6019. –