2012-07-18 3 views
3

REPL에서 범위 지정이 작동하는 방식을 이해하려고합니다. 나는 조슈아 수아레스 (Joshua Suereth)의 스칼라 (Scala) 책 5.1.1 절을 깊이있게 시도했다. 이것은 Windows XP, Java 7 및 스칼라 2.9.1에있다. REPL에 클래스 Dinner을 선언합니다. 바인딩 Dinner이 로컬 범위에 있습니다. 그런 다음 로컬로 바인딩되기 때문에 인스턴스화합니다.REPL에서 선언 된 클래스가 내부적으로 처리되는 방식을 이해하려고 시도합니다.

scala> class Dinner { 
| val veggie="broccoli" 
| def announceDinner(veggie: String){ 
| println("Dinner happens to be tasteless " + veggie + " soup") 
| } 
| } 
defined class Dinner 

scala> new Dinner 
res1: Dinner = [email protected] 

지금까지는 그렇게 좋았습니다. Dinner이라는 이름은 로컬로 바인딩되었으며 new Dinner에 대한 참조를 보유 할 수있는 val x을 만들 수 있습니다.

내가 지금까지 알고있는 것으로부터, REPL은 내부적으로 객체에 위 코드를 래핑 할 것입니다. 좋아요, 스칼라에 대한 지식이 아직 깊지 않아서 클래스가 내부적으로 REPL에 의해 래핑되는 방식을 이해하려고 노력하고 있습니다.

이러한 개체를 평가하는 데 도움이되는 REPL 명령이 있습니까?

+0

복제본 [.scala 프로그램을 실행할 때 실제로 스칼라 런타임/repl 뒤에 나오는 것은 무엇입니까?] (http://stackoverflow.com/questions/7655165/what-really-happens-behind-the-scala-runtime -repl-running-a-scala-program) – sschaef

+0

내가 정말로 알고 싶어하는 것에 더 명확히 추가 할 것이다. 내부적으로 '객체'에 래핑되었을 때 클래스 정의가 유지되는지 확인하려고했습니다. 어쩌면 클래스에서 작동하고 메소드를 호출 할 수 있기 때문에 중요하지 않습니다. 나는 그 글을 전에 보았지만 그것이 나의 질문에 대한 정확한 대답이라고 생각하지 않았고 나는 나의 질문을 게시하는 것을 끝내었다. – ilango

+0

질문을 작은 예제로 업데이트하여 원하는 것을 출력 할 수 있습니까? 나는 네가보고 싶은 것을 이해하지 못한다. – sschaef

답변

3

여기 REPL에서 진행되는 작업에 대해 매우 빠르고 더러운 방법이 있습니다.

스칼라 -Xprint으로 REPL을 호출 : 타이 퍼

scala> class Dinner { 
    | val veggie="broccoli" 
    | def announceDinner(veggie: String){ 
    | println("Dinner happens to be tasteless " + veggie + " soup") 
    | } 
    | } 
[[syntax trees at end of typer]]// Scala source: <console> 
package $line1 { 
    final object $read extends java.lang.Object with ScalaObject { 
    def this(): object $line1.$read = { 
     $read.super.this(); 
    () 
    }; 
    final object $iw extends java.lang.Object with ScalaObject { 
     def this(): object $line1.$read.$iw = { 
     $iw.super.this(); 
     () 
     }; 
     final object $iw extends java.lang.Object with ScalaObject { 
     def this(): object $line1.$read.$iw.$iw = { 
      $iw.super.this(); 
     () 
     }; 
     class Dinner extends java.lang.Object with ScalaObject { 
      def this(): $line1.$read.$iw.$iw.Dinner = { 
      Dinner.super.this(); 
      () 
      }; 
      private[this] val veggie: java.lang.String = "broccoli"; 
      <stable> <accessor> def veggie: java.lang.String = Dinner.this.veggie; 
      def announceDinner(veggie: String): Unit = scala.this.Predef.println("Dinner happens to be tasteless ".+(veggie).+(" soup")) 
     } 
     } 
    } 
    } 
} 

[[syntax trees at end of typer]]// Scala source: <console> 
package $line1 { 
    final object $eval extends java.lang.Object with ScalaObject { 
    def this(): object $line1.$eval = { 
     $eval.super.this(); 
    () 
    }; 
    private[this] val $print: String = { 
     $read.$iw.$iw; 
     "defined class Dinner\012" 
    }; 
    <stable> <accessor> def $print: String = $eval.this.$print 
    } 
} 

defined class Dinner 

Dinner$line1.$read.$iw.$iw에 랩 끝 위에서 확인할 수 있듯이. 이제 다음에 어떻게되는지 보자

[[syntax trees at end of typer]]// Scala source: <console> 
package $line2 { 
    final object $read extends java.lang.Object with ScalaObject { 
    def this(): object $line2.$read = { 
     $read.super.this(); 
    () 
    }; 
    final object $iw extends java.lang.Object with ScalaObject { 
     def this(): object $line2.$read.$iw = { 
     $iw.super.this(); 
     () 
     }; 
     import $line1.$read.$iw.$iw.Dinner; 
     final object $iw extends java.lang.Object with ScalaObject { 
     def this(): object $line2.$read.$iw.$iw = { 
      $iw.super.this(); 
     () 
     }; 
     private[this] val res0: $line1.$read.$iw.$iw.Dinner = new $line1.$read.$iw.$iw.Dinner(); 
     <stable> <accessor> def res0: $line1.$read.$iw.$iw.Dinner = $iw.this.res0 
     } 
    } 
    } 
} 

[[syntax trees at end of typer]]// Scala source: <console> 
package $line2 { 
    final object $eval extends java.lang.Object with ScalaObject { 
    def this(): object $line2.$eval = { 
     $eval.super.this(); 
    () 
    }; 
    lazy private[this] var $result: $line1.$read.$iw.$iw.Dinner = { 
     $eval.this.$print; 
     $line2.$read.$iw.$iw.res0 
    }; 
    private[this] val $print: String = { 
     $read.$iw.$iw; 
     "res0: $line1.$read.$iw.$iw.Dinner = ".+(scala.runtime.ScalaRunTime.replStringOf($line2.$read.$iw.$iw.res0, 1000)) 
    }; 
    <stable> <accessor> def $print: String = $eval.this.$print 
    } 
} 

을 기본적으로 같은 일이 이전하지만 $line1 대신 $line2를 사용하여. $line2.$read.$iw.$iw 바로 앞에 import $line1.$read.$iw.$iw.Dinner이 있습니다.

두 가지 다른 라인에서 컴패니언 개체를 정의하는 것이 효과적이지 않은 이유는 이러한 개체가 서로 다른 개체로 래핑 된 결과가되고 컴패니언을 동일한 범위/소스 파일에 정의해야하는 이유입니다.

+0

많은 도움이됩니다. 그것이 해결책을 원했던 문제입니다. REPL – ilango

+0

에서 어떤 일이 있었는지 확인하려면 scala -Xprint : parser를 사용해보십시오. 좀 더 간결한 결과를 줄 수 있습니다. BTW, 올바른 것으로 질문을 표시하는 것을 잊지 마십시오. :) – pedrofurla

+0

"고맙습니다"할 수 있습니까? 그 stackoverflow에 나쁜 예의로 간주됩니까? 질문을 옳은 것으로 표시하려면 어떻게합니까? 나는 stackoverflow에 새로운 사람이다. – ilango

관련 문제