Scala недетерминированные/кэширующие классы?

У меня очень простая цель: скомпилировать класс Scala, а затем загрузить его из другого Scala script. Проблема заключается в том, что Scala похоже кэширует (не уверен, где) классы, которые я создаю, и не соблюдает последующие изменения.

Следующие строки создают каталог с двумя файлами .scala, компилируют один и запускают другое:

mkdir test
cd test
echo 'class MyClass(s: String)' > MyClass.scala
echo 'val p = new MyClass("ok")' > test.scala
scalac MyClass.scala
scala test.scala # this works
cd ..
rm -rf test

Если я запустил вышеуказанные строки, мне нужно REBOOT MY COMPUTER для следующих ниже строк:

mkdir test
cd test
echo 'class MyClass()' > MyClass.scala
echo 'val p = new MyClass()' > test.scala
scalac MyClass.scala
scala test.scala # this doesn't
cd ..
rm -rf test

Если я не перезагружаюсь, я получаю сообщение об ошибке, что мне не хватает String в моем конструкторе. Не уверен, где в Scala -land он кэширует предыдущий конструктор на основе String.

Ответ 1

Это связано с тем, что бегун scala script запускает резидентный экземпляр сервера компиляции (fsc) в фоновом режиме. Вы сможете найти текущий java процесс с основным классом scala.tools.nsc.CompileServer после запуска вашего первого script.

Обратите внимание, что это происходит только тогда, когда scala используется для запуска script, то есть файла .scala, который не содержит один блок компиляции с основным классом.

Последующие вызовы scala будут использовать этот компилируемый сервер (только при использовании для запуска script), который кэширует информацию о предыдущих прогонах компиляции, следовательно, ошибку.

Вы можете указать scala не использовать fsc при запуске script с помощью

scala -nc test.scala

Вы также можете закрыть этот фоновый экземпляр с помощью

fsc -shutdown

Или reset его кеш с помощью:

fsc -reset