2011-02-07 13 views
5

To łatwiej wyjaśnione kodu:Biorąc pod uwagę wartość jakiegoś typu zależnego od ścieżki, jak mogę uzyskać instancję "kontenera"?

class Bippy { 
    val x = 42 

    class Boppy { 
    val y = "hello world" 
    } 

    val bop = new Boppy 
} 

val bip = new Bippy 
val bop: Bippy#Boppy = bip.bop 

bop się następnie z inną metodą, która musi znaleźć wartość x z zawierającego wystąpienie Bippy. Jakie jest magiczne zaklęcie, aby to zrobić?

Instancja bop pochodzi z kodu, którego nie kontroluję, więc dodawanie nowych metod do Boppy nie jest tutaj możliwe.

Odpowiedz

7

Nie możesz. Przynajmniej nie bez oszustwa. Oto jak oszukiwać.

def getOuter(bop : Bippy#Boppy) = 
    bop.asInstanceOf[{def Bippy$Boppy$$$outer() : Bippy}].Bippy$Boppy$$$outer() 

Oczywiście to bardzo zależy od szczegółów, jak działa scalac dzisiaj i nie ma gwarancji, że będzie działać jutro.

+0

Jest to rozwiązanie, którego używam już :) Ale jak się wydaje nie ma lepszego sposobu, dostajesz zielony tyk, krwawiące oczy i wszystko! –

4

Jak powiedział James, nie można. Jego cheat sprawia, że ​​moje oczy krwawią, a proponuję zrobić coś innego ;-)

Gorąco polecam modyfikację konsumentów bop, jeśli możesz. Zamiast przekazania ich wystąpienie Bippy # Boppy, przekazać im para zawiera wartość typu zależnego i wartość rodzaj zależy,

trait DependentPack { 
    val bippy : Bippy 
    val boppy : bippy.Boppy 
} 

val bip = new Bippy 
val bop = bip.bop 
val dep = new DependentPack { val bippy = bip ; val boppy = bop } 
foo(dep) 

def foo(dp : DependentPack) = { 
    import dp._ 
    // use bippy ... 
    // use boppy ... 
} 

Należy zauważyć, że jest to częściowo obejście braku zależne typy metod (włączone w skalaku poprzez dodanie opcji -yzwiązanych z typem-metod lub -Xexperymentalnych przełączników wiersza poleceń). Gdybyśmy mieli je, a następnie mogliśmy spaść artefaktów jak DependentPack i przepisać powyższe jak

val bip = new Bippy 
val bop = bip.bop 
foo(bip)(bop) 

def foo(bippy : Bippy)(boppy : bippy.Boppy) = { 
    // use bippy ... 
    // use boppy ... 
} 

Trzeba powiedzieć, myślę, mający na utrzymaniu rodzaje metod włączone domyślnie byłoby wysoce pożądane. Nietynkowe zastosowania typów zależnych niesie ze sobą świat bólu pod ich nieobecność, chyba że jesteś bardzo ostrożny.

+0

Myślę, że wziąłem jego problem jako "Mam boppy, które pochodzi z innego miejsca i muszę uzyskać jego Bippy". Jeśli coś takiego jak rozwiązanie Milesa jest możliwe, zrób to. –

+0

Niestety, nie mam również dostępu do 'bip'. Po prostu "bop" i niesforny typ podpisu ... –

+0

Nadal dobre połączenie z zależnym pisaniem! Od czasu do czasu zasługuje na trochę odświeżenia. –

Powiązane problemy