У меня почти всегда есть сессия Scala REPL или два открытых, который делает очень легким дать Java или классам Scala быстрый тест. Но если я изменяю класс и перекомпилировал его, REPL продолжает старый загруженный. Существует ли способ заставить это перезагружать класс, вместо того, чтобы иметь необходимость перезапустить REPL?
Только для предоставления конкретного примера предположите, что у нас есть файл Test.scala:
object Test { def hello = "Hello World" }
Мы компилируем его и запускаем REPL:
~/pkg/scala-2.8.0.Beta1-prerelease$ bin/scala
Welcome to Scala version 2.8.0.Beta1-prerelease
(Java HotSpot(TM) Server VM, Java 1.6.0_16).
Type in expressions to have them evaluated.
Type :help for more information.
scala> Test.hello
res0: java.lang.String = Hello World
Затем мы изменяем исходный файл на
object Test {
def hello = "Hello World"
def goodbye = "Goodbye, Cruel World"
}
но мы не можем использовать его:
scala> Test.goodbye
<console>:5: error: value goodbye is not a member of object Test
Test.goodbye
^
scala> import Test;
<console>:1: error: '.' expected but ';' found.
import Test;
Перезагрузка классов - непростая проблема. На самом деле, это то, что JVM делает очень сложным. Однако у вас есть несколько вариантов:
К сожалению, оба этих инструмента ограничены деталями реализации Scala REPL. Я использую JRebel, и обычно это помогает, но все равно бывают случаи, когда REPL не отражает перезагруженный класс(ы). Тем не менее, это лучше, чем ничего.
Существует альтернатива перезагрузке класса, если цель состоит в том, чтобы не повторять предыдущие команды. REPL имеет команду
:replay
, которая перезапускает среду REPL и воспроизводит все предыдущие допустимые команды. (Недействительные пропускаются, поэтому, если раньше это было неправильно, это не сработает внезапно.) Когда REPL сбрасывается, он перезагружает классы, поэтому новые команды могут использовать содержимое перекомпилированных классов (фактически, старые команды также будут использовать эти перекомпилированные классы).
Это не общее решение, но полезный ярлык для расширения отдельного сеанса с помощью повторно вычисляемого состояния.
Примечание: это относится к голому Scala REPL. Если вы запустите его из SBT или какой-либо другой среды, он может работать или не работать в зависимости от того, как SBT или другая среда упаковывает классы - если вы не обновите то, что находится на фактическом используемом пути к классам, конечно, он выиграет ' т работать!