51

私はほとんどの場合、Scala REPLセッションを1つか2つ開いているので、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;
4

5 に答える 5

41

目標が前のコマンドを繰り返す必要がないことである場合、クラスをリロードする代わりの方法があります。REPLにはコマンドがあります

:replay

これにより、REPL環境が再起動し、以前のすべての有効なコマンドが再生されます。(無効なものはスキップされるので、以前に間違っていた場合、突然機能しません。)REPLがリセットされると、クラスがリロードされるため、新しいコマンドは再コンパイルされたクラスの内容(実際には古いコマンド)を使用できます。これらの再コンパイルされたクラスも使用します)。

これは一般的な解決策ではありませんが、再計算可能な状態で個々のセッションを拡張するための便利なショートカットです。

注:これは、ベアのScalaREPLに適用されます。SBTまたは他の環境から実行する場合、SBTまたは他の環境がクラスをパッケージ化する方法に応じて、機能する場合と機能しない場合があります。実際に使用されているクラスパスにあるものを更新しない場合は、もちろん機能します。動作します!

于 2010-03-18T23:06:41.510 に答える
32

クラスのリロードは簡単な問題ではありません。実際、これはJVMが非常に困難にしていることです。ただし、いくつかのオプションがあります。

  • ScalaREPLをデバッグモードで起動します。JVMデバッガーには、メソッドレベルで機能するリロードが組み込まれています。あなたが与えたケースでは役に立ちませんが、メソッドの実装を変更するような単純なものを処理します。
  • JRebel(http://www.zeroturnaround.com/jrebel)を使用します。JRebelは基本的に、JVM用のスーパーチャージされたクラスリロードソリューションです。メンバーの追加/削除、新規/削除されたクラス、定義の変更などを処理できます。処理できないのは、クラス階層の変更(たとえば、スーパーインターフェイスの追加)だけです。これは無料のツールではありませんが、Scalaコンパイルユニットに限定された補完的なライセンスを提供します。

残念ながら、これらは両方ともScalaREPLの実装の詳細によって制限されています。私はJRebelを使用しており、通常はそれでうまくいきますが、REPLがリロードされたクラスを反映しない場合があります。それでも、何もないよりはましです。

于 2010-03-18T18:57:24.367 に答える
8

要件を満たすコマンドがあります

:load path/to/file.scala

これにより、scalaソースファイルがリロードされ、クラスに再コンパイルされます。その後、コードを再生できます。

于 2014-09-26T07:53:03.783 に答える
7

これは私のために働きます...

新しいソースファイル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
于 2014-09-26T20:37:03.593 に答える
2

.scalaファイルがREPLを開始するディレクトリにある場合は、フルパスを省略し、を入力して:load myfile.scalaからインポートすることができます。

于 2015-10-07T20:15:15.950 に答える