임의의 스칼라 코드 위치 동안 인터프리터에 드롭


84

저는 Python 배경에서 왔으며 코드의 어느 시점에서든 추가 할 수 있습니다.

import pdb; pdb.set_trace()

그리고 런타임에 나는 그 지점에서 인터랙티브 인터프리터로 떨어질 것입니다. 스칼라에 상응하는 것이 있습니까, 아니면 런타임에 불가능합니까?


7
"광고의 진실"이라는 정신으로 스칼라에는 통역사가 없습니다. REPL은 "컴파일 및 이동"입니다. 즉, 원하는 경우 REPL 코드 (컴파일러 포함)를 응용 프로그램에 통합 할 수 있습니다 (아래 참조)
Randall Schulz

1
그러나 REPL은 REPL 실행 코드에서 명시적이고 힘들게 바인딩하는 것을 제외하고는 실행중인 컨텍스트에 대한 지식없이 실행됩니다. 아래를 참조하십시오. 파이썬에서는 훨씬 더 나은 실행 컨텍스트에 도달한다고 생각합니다. 어쨌든, stackoverflow.com/questions/24674288/… 더 최신입니다.
matanster 2014 년

답변:


78

예, Scala 2.8에서 가능합니다. 이 작업을 수행하려면 클래스 경로에 scala-compiler.jar를 포함해야합니다. 를 사용하여 스칼라 프로그램을 호출하면 scala자동으로 수행됩니다 (또는 제가 만든 테스트에 나타납니다).

그런 다음 다음과 같이 사용할 수 있습니다.

import scala.tools.nsc.Interpreter._

object TestDebugger {
  def main(args: Array[String]) {
    0 to 10 foreach { i =>
      breakIf(i == 5, DebugParam("i", i))
      println(i)
    }
  }
}

여러 DebugParam인수를 전달할 수 있습니다 . REPL이 나오면 오른쪽에있는 값은 왼쪽에 입력 한 이름의 값에 바인딩됩니다. 예를 들어 다음과 같이 해당 줄을 변경하면 :

      breakIf(i == 5, DebugParam("j", i))

그러면 다음과 같이 실행됩니다.

C:\Users\Daniel\Documents\Scala\Programas>scala TestDebugger
0
1
2
3
4
j: Int

scala> j
res0: Int = 5

을 입력하여 실행을 계속합니다 :quit.

또한 무조건 호출하여 REPL로 떨어질 수 break수신 ListDebugParam대신 가변 인자의. 다음은 전체 예제, 코드 및 실행입니다.

import scala.tools.nsc.Interpreter._

object TestDebugger {
  def main(args: Array[String]) {
    0 to 10 foreach { i =>
      breakIf(i == 5, DebugParam("j", i))
      println(i)
      if (i == 7) break(Nil)
    }
  }
}

그리고:

C:\Users\Daniel\Documents\Scala\Programas>scalac TestDebugger.scala

C:\Users\Daniel\Documents\Scala\Programas>scala TestDebugger
0
1
2
3
4
j: Int

scala> j
res0: Int = 5

scala> :quit
5
6
7

scala> j
<console>:5: error: not found: value j
       j
       ^

scala> :quit
8
9
10

C:\Users\Daniel\Documents\Scala\Programas>

3
이로 인해 scala.tools.nsc.MissingRequirementError: object scala not found.Scala 2.8에서 오류가 발생할 수 있습니다 . 명시 적으로 Scalac의 설정을 호스트 프로세스의 클래스 경로를 통과해야하지만, break그리고 breakIf이 작업을 수행하지 않습니다. 여기에 패치 된 버전 break이 있습니다 : gist.github.com/290632
retronym

@retronym 재미 있네요, 방금 여기에서 일했습니다. Paulp에게 보내십시오. 그는이 일이 어쨌든 변경 될 것이라고 언급했습니다.
Daniel C. Sobral

IntelliJ에서 실행하는 JUnit 테스트에서 시도했습니다. IntelliJ는 java -classpath .... scala -classpath대신 사용하면 잘 작동 할 것 같습니다.
retronym

4
모듈의 종속성이므로 클래스 경로에 있습니다. 2.8은 java -classpath호스트 프로세스 의 내용 을 scalac : old.nabble.com/…
retronym

1
@Huur Răzvan Panda의 답변 을 참조하십시오 .
Daniel C. Sobral

24

Daniel의 답변에 추가하기 위해 Scala 2.9부터 breakbreakIf메서드는 scala.tools.nsc.interpreter.ILoop. 또한 DebugParam현재 NamedParam입니다.


jline 을 종속성 으로 추가해야합니다 .
schmmd 2011

8
새로운 사용법에 대한 예제를 작성해 주시겠습니까?

24

IntelliJ IDEA :

  1. 디버그 모드에서 실행하거나 원격 디버거 연결
  2. 중단 점을 설정하고 도달 할 때까지 실행
  3. Evaluate Expression( Alt+ F8, 메뉴 : Run-> Evaluate Expression) 창을 열어 임의의 Scala 코드를 실행합니다.
  4. 실행할 코드 조각 또는 표현식을 입력하고 평가를 클릭하십시오.
  5. Alt+를 입력 V하거나 평가를 클릭하여 코드 조각을 실행합니다.

식:

스칼라 2.10으로 모두 breakbreakIf에서 제거되었습니다 ILoop.

통역사에 침입하려면 ILoop직접 협력해야 합니다.

먼저 scala compiler라이브러리를 추가하십시오 . Eclipse Scala의 경우 프로젝트 => Build Path=> Add Libraries...=>를 마우스 오른쪽 버튼으로 클릭하십시오 Scala Compiler.

그런 다음 인터프리터를 시작하려는 위치에서 다음을 사용할 수 있습니다.

import scala.tools.nsc.interpreter.ILoop
import scala.tools.nsc.interpreter.SimpleReader
import scala.tools.nsc.Settings

val repl = new ILoop
repl.settings = new Settings
repl.settings.Yreplsync.value = true
repl.in = SimpleReader()
repl.createInterpreter()

// bind any local variables that you want to have access to
repl.intp.bind("row", "Int", row)
repl.intp.bind("col", "Int", col)

// start the interpreter and then close it after you :quit
repl.loop()
repl.closeInterpreter()

Eclipse Scala에서 인터프리터는 Console보기 에서 사용할 수 있습니다 .


18
그건 정말 나쁘다. :(
Daniel C. Sobral 2013-10-28

@Daniel 왜 그게 끔찍한가요?
Hakkar

14
프로그램의 한 지점에서 디버깅하는 목표와는 전혀 관련이없고 대신 REPL을 실행하는 메커니즘과 관련된 많은 상용구를 추가하기 때문입니다.
Daniel C. Sobral 2013 년

1
@Daniel 스칼라 2.10에 더 좋은 방법이 있습니까?
roterl 2014-06-08

@roterl 위의 문제는 무엇입니까?
Daniel C. Sobral 2014-06-09
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.