2012-07-18 56 views
3

我想了解如何在REPL中作用於範圍。我試着深入瞭解Joshua Suereth的書Scala的第5.1.1節。這是在Windows XP,Java 7和Scala 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在本地綁定,我們也可以構建一個val x,可以保存對new Dinner的引用。

從我目前所瞭解的情況來看,REPL會將上面的代碼封裝在對象內部。好吧,我對Scala的瞭解還不夠深入,我正試圖理解如何通過REPL內部包裝Class。

是否有REPL命令可以幫助我評估這些對象?

+0

[scala runtime/repl運行.scala程序時真的發生了什麼?](http://stackoverflow.com/questions/7655165/what-really-happens-behind-the-scala-runtime -repl-when-running-a-scala-program) – sschaef 2012-07-18 20:01:04

+0

我會爲我真正想要理解的東西增加更多的清晰度。我試圖找出當它被內部封裝到一個'對象'時,類定義是否被保留。也許這並不重要,因爲我可以在類上操作並調用它的方法?我之前看過那篇文章,但並不認爲這是我的問題的確切答案,我最終發佈了我的問題。 – ilango 2012-07-18 21:32:54

+0

你能否用一個小例子更新你的問題?我不明白你想看到什麼。 – sschaef 2012-07-18 21:42:36

回答

3

這是一個非常快速和骯髒的方式,以在REPL中發生的事情。

調用REPL使用Scala -Xprint:打字員

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 
    } 
} 

基本上同樣的事情之前,但使用$line2代替$line1。請注意0​​之前的import $line1.$read.$iw.$iw.Dinner

這樣我們可以看到爲什麼在兩個不同的行中定義伴隨對象不起作用,它們最終會被包裝到不同的對象中,同伴需要在同一範圍/源文件中定義。

+0

這有很大的幫助。這是我想要解決的問題。要查看REPL中發生了什麼 – ilango 2012-07-19 18:38:47

+0

您還可以嘗試scala -Xprint:parser,它可能會給出更簡潔的結果。順便說一句,不要忘記標記問題是正確的。 :) – pedrofurla 2012-07-19 18:55:39

+0

我可以「謝謝你」嗎?在stackoverflow上被認爲是不好的禮儀嗎?我如何將問題標記爲正確?我是新的stackoverflow。 – ilango 2012-07-19 19:06:18