repl online scala read-eval-print-loop

online - ¿Cómo volver a cargar una clase o paquete en Scala REPL?



repl python (5)

Casi siempre tengo una sesión de Scala REPL o dos abiertas, lo que hace que sea muy fácil dar una prueba rápida a las clases de Java o Scala. Pero si cambio una clase y la vuelvo a compilar, la REPL continúa con la anterior cargada. ¿Hay alguna manera de hacer que vuelva a cargar la clase, en lugar de tener que reiniciar el REPL?

Solo para dar un ejemplo concreto, supongamos que tenemos el archivo Test.scala:

object Test { def hello = "Hello World" }

Compilamos y comenzamos el 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

Luego cambiamos el archivo fuente a

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

pero no podemos usarlo:

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;


Esto funciona para mí ...

Si su nuevo archivo fuente Test.scala tiene un aspecto similar a este ...

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

Primero debe cargar los nuevos cambios en la consola de Scala (REPL).

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

A continuación, vuelva a importar el paquete para que pueda consultar el nuevo código en la consola de Scala.

import com.tests.Test

Ahora disfruta de tu nuevo código sin reiniciar tu sesión :)

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


Existe una alternativa para volver a cargar la clase si el objetivo es no tener que repetir comandos anteriores. El REPL tiene el comando

:replay

que reinicia el entorno REPL y reproduce todos los comandos válidos anteriores. (Los inválidos se omiten, por lo que si antes era incorrecto, no funcionarán de repente). Cuando se restablece el REPL, vuelve a cargar clases, por lo que los nuevos comandos pueden usar los contenidos de las clases recompiladas (de hecho, los comandos anteriores) también usará esas clases recompiladas).

Esta no es una solución general, pero es un atajo útil para extender una sesión individual con un estado recalculable.

Nota: esto se aplica a Scala REPL. Si lo ejecuta desde SBT o algún otro entorno, puede funcionar o no dependiendo de cómo SBT o el otro entorno empaca las clases; si no actualiza lo que está en la ruta de clase real que se está utilizando, por supuesto que ganó '' t trabajo!


Hay un comando que cumple con su requisito

:load path/to/file.scala

que volverá a cargar el archivo fuente scala y volverá a compilarse en clases, luego podrá volver a reproducir el código


La recarga de clase no es un problema fácil. De hecho, es algo que la JVM hace muy difícil. Sin embargo, tienes un par de opciones:

  • Inicie el Scala REPL en modo de depuración. El depurador JVM tiene una recarga incorporada que funciona en el nivel de método. No lo ayudará con el caso que dio, pero manejaría algo simple como cambiar la implementación de un método.
  • Use JRebel ( http://www.zeroturnaround.com/jrebel ). JRebel es básicamente una solución de recarga de clase súper cargada para la JVM. Puede manejar la adición / eliminación de miembros, las clases nuevas / eliminadas, los cambios de definición, etc. Casi lo único que no puede manejar son los cambios en la jerarquía de clases (por ejemplo, agregar una super-interfaz). No es una herramienta gratuita, pero ofrecen una licencia complementaria que se limita a las unidades de compilación de Scala.

Desafortunadamente, ambos están limitados por los detalles de implementación de Scala REPL. Yo uso JRebel, y generalmente funciona, pero todavía hay casos en que el REPL no reflejará la (s) clase (s) recargada (s). Aún así, es mejor que nada.


Si el archivo .scala está en el directorio donde inicia el REPL, puede omitir la ruta completa, simplemente ponga :load myfile.scala , y luego importar.