2012-07-01 32 views
6

stavo cercando di seguire l'esempio di un'altra domanda, e mi sono imbattuto in qualcosa che non so spiegare:Strano comportamento con la riflessione a Scala

scala> import scala.reflect.runtime.{currentMirror => m} 
import scala.reflect.runtime.{currentMirror=>m} 

scala> m.mkToolBox() 
<console>:12: error: value mkToolBox is not a member of reflect.runtime.universe.Mirror 
       m.mkToolBox() 
       ^

scala> import scala.tools.reflect.ToolBox 
import scala.tools.reflect.ToolBox 

scala> m.mkToolBox() 
res3: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = [email protected] 

Come mai mkToolBox non è un membro del m prima di importare ToolBox, ma è dopo?

risposta

2

Se esamino con reify, vedo questo:

scala> reify{ m.mkToolBox() }.tree 
res4: reflect.runtime.universe.Tree = 
{ 
    val qual$1 = scala.tools.reflect.`package`.ToolBox(scala.reflect.runtime.`package`.m); 
    val x$1 = qual$1.mkToolBox$default$1; 
    val x$2 = qual$1.mkToolBox$default$2; 
    qual$1.mkToolBox(x$1, x$2) 
} 

Questo significa che c'è un metodo chiamata a una funzione denominata ToolBox all'interno dell'oggetto pacchetto scala.tools.reflect. Non è un oggetto, perché reify esporrà il metodo apply.

Quindi, anche se lo API Docs for the Compiler non mostra altro che il tratto sul lato sinistro, se si guarda il pacchetto vedrete una definizione di metodo implicita.

PS: Sì, questa era una vera domanda. Il pensiero di un metodo di partenza maiuscolo con lo stesso nome di un tratto non mi è venuto in mente, finché non ho pensato di reificare la cosa per ottenere l'albero.

+0

Quello che faccio in tali situazioni: guardo alle fonti per riconoscere cosa sta succedendo lì. ;) – sschaef

+0

@Antoras E 'passato molto tempo da quando qualche codice di Scala mi ha lasciato confuso sul suo significato. La spiegazione è piuttosto ovvia, ma il pensiero di 'ToolBox' come metodo non mi è venuto in mente. –

3

ToolBox è una classe implicita che papponi mkToolBox su Mirror. Stessa storia con Eval, che fa il pappone eval.

+0

Una classe implicita? Questo spiega certamente il metodo chiamato in modo anticonvenzionale. –