scalap
いくつかのケース クラスのフィールド名を読み上げるために使用しています (この質問で説明されているように)。ケースクラスとそれらを分析するために使用するコードの両方scalap
がコンパイルされ、クラスパス上の jar ファイルに配置されています。
今、このコードを使用するスクリプトを実行したいので、指示に従って次のようなものを思いつきました
::#!
@echo off
call scala -classpath *;./libs/* %0 %*
goto :eof
::!#
//Code relying on pre-compiled code that uses scalap
これは機能しません:
java.lang.ClassCastException: scala.None$ は scala.tools.nsc.interpreter.ByteCode$.caseParamNamesForPath(ByteCode. scala:45) で scala.Option にキャストできません。scala.tools.nsc.interpreter.ProductCompletion.caseNames( ProductCompletion.scala:22)
ただし、すべてをコンパイルすると、コードは正常に機能します。のような追加scala
のオプションを試してみ-savecompiled
ましたが、これは役に立ちませんでした。これはバグですか、それとも原則として機能しませんか? (もしそうなら、誰かが理由を説明できますか?私が言ったように、分析されるケースクラスscalap
はコンパイルされます。)
注: Scala 2.9.1-1 を使用しています。
編集
これが私が本質的にやろうとしていることです(ケースクラスの複数のインスタンスを作成する簡単な方法を提供します):
//This is pre-compiled:
import scala.tools.nsc.interpreter.ProductCompletion
//...
trait MyFactoryTrait[T <: MyFactoryTrait[T] with Product] {
this: T =>
private[this] val copyMethod = this.getClass.getMethods.find(x => x.getName == "copy").get
lazy val productCompletion = new ProductCompletion(this)
/** The names of all specified fields. */
lazy val fieldNames = productCompletion.caseNames //<- provokes the exception (see above)
def createSeq(...):Seq[T] = {
val x = fieldNames map { ... } // <- this method uses the fieldNames value
//[...] invoke copyMethod to create instances
}
// ...
}
//This is pre-compiled too:
case class MyCaseClass(x: Int = 0, y: Int = 0) extends MyFactoryTrait[MyCaseClass]
//This should be interpreted (but crashes):
val seq = MyCaseClass().createSeq(...)
注: Scala 2.9.2 に移行しましたが、エラーは同じままです (おそらくバグではありません)。