代码之家  ›  专栏  ›  技术社区  ›  Rex Kerr

如何在Scala REPL中重新加载类或包?

  •  40
  • Rex Kerr  · 技术社区  · 14 年前

    举个具体的例子,假设我们有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;
    
    5 回复  |  直到 9 年前
        1
  •  31
  •   Daniel Spiewak    14 年前

    • 在调试模式下启动Scala REPL。JVM调试器有一些在方法级工作的内置重新加载。它不会帮助您处理您给出的案例,但是它可以处理一些简单的事情,比如更改方法实现。
    • 使用JRebel( http://www.zeroturnaround.com/jrebel ). JRebel基本上是针对 JVM。它能处理 成员的添加/删除、新的/删除的类、定义的更改等等,这几乎是它唯一需要做的事情 句柄是类层次结构中的更改(例如,添加一个超级接口)

    不幸的是,这两种方法都受到scalarepl实现细节的限制。我使用JRebel,它通常能做到这一点,但是仍然有REPL不能反映重新加载的类的情况。不过,总比什么都没有强。

        2
  •  41
  •   Rex Kerr    9 年前

    如果目标是不必重复前面的命令,则可以选择重新加载类。REPL有命令

    :replay
    

    它重新启动REPL环境并回放所有以前的有效命令(当REPL被重置时,它会重新加载类,因此新命令可以使用重新编译的类的内容(事实上,旧命令也会使用那些重新编译的类)。

    这不是一个通用的解决方案,而是一个有用的快捷方式来扩展具有可重新计算状态的单个会话。

    注意:这适用于裸Scala REPL。如果您从SBT或其他环境运行它,它可能工作,也可能不工作,这取决于SBT或其他环境如何打包类——如果您不更新实际使用的类路径上的内容,它当然不会工作!

        3
  •  8
  •   jiahut    10 年前

    有一个命令符合你的要求

    :load path/to/file.scala
    

    它将重新加载scala源文件并重新编译为类,然后您可以重放您的代码

        4
  •  7
  •   cevaris    10 年前

    这对我有用。。。。

    Test.scala 看起来像这样。。。

    package com.tests
    
    object Test {
      def hello = "Hello World"
      def goodbye = "Goodbye, Cruel World"
    }
    

    首先必须将新的更改加载到Scala控制台(REPL)中。

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

    然后重新导入包,以便可以在Scala控制台中引用新代码。

    import com.tests.Test
    

    现在无需重新启动会话即可享受新代码:)

    scala> Test.goodbye
    res0: String = Goodbye, Cruel World
    
        5
  •  2
  •   Ignacio    9 年前

    如果.scala文件在您启动REPL的目录中,您可以ommit完整路径,只需将 :load myfile.scala