2010-11-08 10 views
8

Comme demandé dans this thread sur la liste de diffusion Scala, comment puis-je créer un Scala REPL intégré qui hérite du chemin de classe du programme parent? Supposons que le programme parent Scala soit lancé en utilisant scala -cp <classpath> ...; <classpath> peut-il être accédé en tant que chaîne et utilisé pour initialiser le REPL intégré? (Le Java classpath, disponible via System.getProperty("java.class.path"), semble différer de la classpath Scala.)Scala REPL intégré héritant du chemin de classe parent

Sinon, peut-être le noyé Scala REPL peut hériter ou construire son ClassLoader du processus parent (ScalaDays Michael Dürig 2010 talk pourraient être pertinents). Est-ce l'approche recommandée?

+0

Je n'avais jamais entendu parler d'un interpréteur Scala. Où peux-je le recevoir? – ziggystar

+0

Par interprète, je veux dire la Scala REPL. Il vient avec le compilateur Scala. C'est ce que vous obtenez lorsque vous exécutez l'exécutable 'scala' depuis la ligne de commande. Cette question concerne l'intégration d'un REPL dans un programme Scala en cours d'exécution. –

+0

J'ai modifié votre réponse pour indiquer que vous voulez dire REPL. – ziggystar

Répondre

6

Je suis en train de faire la même chose, et je viens de trouver un moyen par mon Googling:

lazy val urls = java.lang.Thread.currentThread.getContextClassLoader match { 
    case cl: java.net.URLClassLoader => cl.getURLs.toList 
    case _ => error("classloader is not a URLClassLoader") 
} 
lazy val classpath = urls map {_.toString} 

Le code ci-dessus vous obtient le classpath dans le contexte actuel.

settings.classpath.value = classpath.distinct.mkString(java.io.File.pathSeparator) 

Mettez ça dans votre settings.classpath et vous devriez être en mesure de tirer jusqu'à l'expédition ou quelle que soit la bibliothèque dont vous avez besoin.

+0

Merci, c'est utile.La solution de contournement que j'avais choisi était d'utiliser la variable d'environnement Java classpath (c'est-à-dire '$ CLASSPATH') au lieu du chemin de classe Scala. Le classpath Java est hérité par l'interpréteur intégré, puis l'option "usejavacp" fonctionne. –

2

définissez la propriété usejavacp true:

val settings = new scala.tools.nsc.Settings 
settings.usejavacp.value = true 
+0

Cette technique ne semble pas ajouter le classpath _Scala_ à l'interpréteur nouvellement créé. Comme documenté dans 'scala.tools.nsc.StandardScalaSettings.scala', cette option inclut seulement' java.class.path' dans la résolution de classpath. –

+0

Jetez un oeil à https://lampsvn.epfl.ch/trac/scala/wiki/Classpath et le code source associé à http://lampsvn.epfl.ch/svn-repos/scala/scala-msil/trunk/ src/compilateur/scala/tools/util/PathResolver.scala Ceux-ci décrivent la gestion du chemin de classe en cours dans quelques détails. – michid

+0

Je ne suis pas sûr de savoir comment utiliser cette information. Est-il possible d'accéder à l'instance de scala.tools.util.PathResolver dans le programme en cours d'exécution? Si c'est le cas, je peux réutiliser son objet Settings pour l'interpréteur intégré que je crée. –

1

Il ne semble pas être un moyen facile d'accéder à la « Scala classpath » à partir d'un programme Scala en cours d'exécution (en revanche, le « Java classpath » est disponible via la propriété système java.class.path). On aimerait accéder, par exemple, au champ Calculated.userClasspath dans l'instance de scala.tools.PathResolver, mais ce dernier ne semble pas accessible. La solution la plus simple consiste peut-être à modifier le script de lancement scala pour stocker la chaîne de paramètres -classpath dans une variable d'environnement.

En supposant que la classpath Scala désirée peut être déterminée, il peut être transmis à l'interpréteur Scala embarqué via: settings.classpath.value = ...

Mise à jour: bien que la chaîne de classpath Scala peut ne pas être directement accessible depuis le moteur d'exécution Scala, @ Eugene souligne qu'il peut être extrait du classloader de contexte. Merci.