How to reload a class or package in Scala REPL?

僤鯓⒐⒋嵵緔 提交于 2019-11-28 18:34:55

问题


I almost always have a Scala REPL session or two open, which makes it very easy to give Java or Scala classes a quick test. But if I change a class and recompile it, the REPL continues with the old one loaded. Is there a way to get it to reload the class, rather than having to restart the REPL?

Just to give a concrete example, suppose we have the file Test.scala:

object Test { def hello = "Hello World" }

We compile it and start the 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

Then we change the source file to

object Test {
  def hello = "Hello World"
  def goodbye = "Goodbye, Cruel World"
}

but we can't use it:

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;

回答1:


Class reloading is not an easy problem. In fact, it's something that the JVM makes very difficult. You do have a couple options though:

  • Start the Scala REPL in debug mode. The JVM debugger has some built-in reloading which works on the method level. It won't help you with the case you gave, but it would handle something simple like changing a method implementation.
  • Use JRebel (http://www.zeroturnaround.com/jrebel). JRebel is basically a super-charged class reloading solution for the JVM. It can handle member addition/removal, new/removed classes, definition changes, etc. Just about the only thing it can't handle is changes in class hierarchy (adding a super-interface, for example). It's not a free tool, but they do offer a complementary license which is limited to Scala compilation units.

Unfortunately, both of these are limited by the Scala REPL's implementation details. I use JRebel, and it usually does the trick, but there are still cases where the REPL will not reflect the reloaded class(es). Still, it's better than nothing.




回答2:


There is an alternative to reloading the class if the goal is to not have to repeat previous commands. The REPL has the command

:replay

which restarts the REPL environment and plays back all previous valid commands. (The invalid ones are skipped, so if it was wrong before, it won't suddenly work.) When the REPL is reset, it does reload classes, so new commands can use the contents of recompiled classes (in fact, the old commands will also use those recompiled classes).

This is not a general solution, but is a useful shortcut to extend an individual session with re-computable state.

Note: this applies to the bare Scala REPL. If you run it from SBT or some other environment, it may or may not work depending on how SBT or the other environment packages up classes--if you don't update what is on the actual classpath being used, of course it won't work!




回答3:


There is an command meet you requirement

:load path/to/file.scala

which will reload the scala source file and recompiled to classes , then you can replay you code




回答4:


This works for me....

If your new source file Test.scala looks something like this...

package com.tests

object Test {
  def hello = "Hello World"
  def goodbye = "Goodbye, Cruel World"
}

You first have to load the new changes into Scala console (REPL).

:load src/main/scala/com/tests/examples/Test.scala

Then re-import the package so you can reference the new code in Scala console.

import com.tests.Test

Now enjoy your new code without restarting your session :)

scala> Test.goodbye
res0: String = Goodbye, Cruel World



回答5:


If the .scala file is in the directory where you start the REPL you can ommit the full path, just put :load myfile.scala, and then import.



来源:https://stackoverflow.com/questions/2471947/how-to-reload-a-class-or-package-in-scala-repl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!