2010-11-08 3 views
8

Как указано в this thread в списке рассылки Scala, как я могу создать встроенную Scala REPL, которая наследует путь к классам родительской программы? Предположим, что исходная программа Scala запущена с использованием scala -cp <classpath> ...; может ли <classpath> быть доступным как строка и использоваться для инициализации встроенного REPL? (The Java классы, доступны через System.getProperty("java.class.path"), по-видимому, отличаются от пути к классам Scala.)Встраиваемая Scala REPL наследует родительский путь к классам

В качестве альтернативы, возможно, внедренный Scala РЕПЛ может наследовать или построить его ClassLoader от родительского процесса (ScalaDays Майклом ранее Дюриг в 2010 тока может иметь отношение). Это рекомендуемый подход?

+0

Я никогда не слышал о переводчике Scala. Где я могу получить это? – ziggystar

+0

Под интерпретатором я имею в виду Scala REPL. Он поставляется с компилятором Scala. Это то, что вы получаете, когда исполняете исполняемый файл 'scala' из командной строки. Этот вопрос связан с вложением REPL в текущую программу Scala. –

+0

Я отредактировал ваш ответ, чтобы отразить, что вы имеете в виду REPL. – ziggystar

ответ

6

Я пытаюсь сделать то же самое, и я только что нашел мой путь путем 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} 

Приведенный выше код получает вас в путь к классам текущего контекста.

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

Put, что в ваш settings.classpath и вы должны быть в состоянии запустить отправку или любой библиотеке, что вам нужно.

+0

Спасибо, это полезно.Обходной путь, на который я остановился, состоял в том, чтобы вместо переменной класса Scala использовать переменную окружения Java classpath (т. Е. '$ CLASSPATH'). Путь Java classpath наследуется встроенным интерпретатором, а затем используется опция «usejavacp». –

2

установить usejavacp свойства верно:

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

Этот метод, похоже, не добавляет путь класса _Scala_ к вновь созданному интерпретатору. Как указано в 'scala.tools.nsc.StandardScalaSettings.scala', эта опция включает только' java.class.path' в разрешении пути к классам. –

+0

Посмотрите на https://lampsvn.epfl.ch/trac/scala/wiki/Classpath и соответствующий исходный код на странице http://lampsvn.epfl.ch/svn-repos/scala/scala-msil/trunk/ src/compiler/scala/tools/util/PathResolver.scala Они описывают текущую обработку пути класса довольно подробно. – michid

+0

Я не уверен, как использовать эту информацию. Есть ли способ получить доступ к экземпляру scala.tools.util.PathResolver в текущей исполняемой программе? Если это так, я могу повторно использовать его объект «Настройки» для встроенного интерпретатора, который я создаю. –

1

Там, кажется, не быть простым способом получить доступ к «Scala классов» внутри работающей программы Scala (в отличии от «Java классов» являются доступный через системное свойство java.class.path). Хотелось бы получить доступ, например, к полю Calculated.userClasspath в случае scala.tools.PathResolver, но последнее не представляется доступным. Возможно, самый простой способ - изменить сценарий запуска scala для хранения строки параметров -classpath в переменной окружения.

Предполагая, что желаемый Scala путь к классам может быть определена, он может быть передан на встроенный интерпретатор Scala с помощью: settings.classpath.value = ...

Update: хотя путь к классам строки Scala не могут быть непосредственно достижима из среды выполнения Scala, @ Евгений указывает, что его можно извлечь из контекстного загрузчика классов. Благодарю.

Смежные вопросы