Nice programing

Scala의 "eval"

nicepro 2020. 12. 26. 16:37
반응형

Scala의 "eval"


Scala를 사용하여 Java 애플리케이션을 스크립팅 할 수 있습니까?

Java에서 Scala 코드를로드하고 실행 범위 (호스트 애플리케이션에 의해 노출 된 데이터)를 설정하고 평가하고 결과 개체를 검색해야합니다.

Scala 문서는 Java에서 컴파일 된 Scala 코드를 호출하는 것이 얼마나 쉬운 지 보여줍니다 (일반 JVM 바이트 코드로 바뀌기 때문입니다).

그러나 어떻게 즉석에서 Scala 표현식을 평가할 수 있습니까 (Java에서 또는 Scala 내에서 더 쉬운 경우)?

다른 많은 언어의 경우 javax.scripting 인터페이스가 있습니다. Scala는이를 지원하지 않는 것 같고, 사전 컴파일에 의존하지 않는 Java / Scala 상호 운용성 문서에서 아무것도 찾을 수 없습니다.


Scala는 스크립팅 언어가 아닙니다. 스크립팅 언어처럼 보일있으며 사람들은 그 목적을 위해 그것을 옹호 할 수 있지만 실제로 JSR 223 스크립팅 프레임 워크 (동적 유형 언어를 지향하는)에 잘 맞지 않습니다. 원래 질문에 답하기 위해 Scala에는 evalJava에 eval. 이러한 함수는 본질적으로 정적 특성을 고려할 때 이러한 언어 중 하나에 실제로 의미가 없습니다.

제 충고 : 필요하지 않도록 코드를 재고 해보세요 eval(루비처럼 코드가있는 언어에서도 거의하지 않습니다). 또는 응용 프로그램의이 부분에 대해 Scala를 전혀 사용하고 싶지 않을 수도 있습니다. 정말로 필요한 경우 evalJRuby를 사용해보십시오. JRuby, Scala 및 Java는 매우 잘 어울립니다. 시스템의 일부는 Java로, 일부는 Scala로, 다른 일부 eval는 Ruby로 만드는 것은 매우 쉽습니다 .


이제 2011 년이되었습니다. scala.tools.nsc.Interpreter

http://blog.darevay.com/2009/01/remedial-scala-interpreting-scala-from-scala/ 참조


Scala는 2.11 ( https://issues.scala-lang.org/browse/SI-874 ) 에서 JSR-223에 대한 공식 지원을 추가했습니다 .

따라서 Daniel Spiewak의 현재 승인 된 답변 (필요하지 않은 방식으로 다시 생각하는 것에 대해)에 대한 고려 사항을 고려한 후에도 여전히 필요하다면 공식 대안이되어야합니다.


스칼라 코드를 가져 와서 클래스로 래핑하고 해당 클래스를 컴파일하고 리플렉션을 사용하여 새 인스턴스를 만든 다음 호출하여 "eval"을 에뮬레이션 할 수 있습니다. 약간 복잡하고 스칼라 컴파일러는 초기화하는 데 매우 느리지 만 (약 2 초 정도) 제대로 작동합니다.

여기에 "util-eval"이라는 라이브러리가 있습니다 : https://github.com/twitter/util/

문제의 코드는 여기에 있습니다 : https://github.com/twitter/util/blob/master/util-eval/src/main/scala/com/twitter/util/Eval.scala

다음과 같이 작동합니다.

val sum = Eval[Int]("1 + 1")
// sum will be 2

이것은 좋은 방법 인 경우 I는 잘 모르겠지만, 내가 사용하여이 문제를 해결 toolbox.parse하고toolbox.eval

Scala에서 평가를 받으려면 다음을 수행해야합니다.

  1. 스칼라 반사 가져 오기

libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.11.7"

  1. 도구 상자에서 평가 사용 :

  import scala.reflect.runtime.currentMirror
  import scala.tools.reflect.ToolBox
  val toolbox = currentMirror.mkToolBox()

  val as = "2*(2+3)"
  val compe = toolbox.eval(toolbox.parse(as))

  println(compe.getClass) // prints class java.lang.Integer
  println(compe) // prints 10


항상 scalac을 사용하여 스칼라 클래스를 컴파일 한 다음 해당 클래스를 동적으로로드 할 수 있습니다. 그러나 나는 당신이 추구하는 것이 아니라고 생각합니다.

참조 URL : https://stackoverflow.com/questions/1183645/eval-in-scala

반응형