2013-08-28 11 views
11

mam następujące makro definiując klasę i powrocie instancję tej klasy (z Scala 2.10.2 i wtyczki makro):Metoda nie mogą być dostępne w Makro generowanej klasy

def test[T] = macro testImpl[T] 

def testImpl[T : c.WeakTypeTag](c: Context): c.Expr[Any] = { 
    import c.universe._ 
    val className = newTypeName("Test") 

    c.Expr { q""" 
    class $className { 
     def method = 1 
    } 
    new $className 
    """} 
} 

Kiedy wywołać makro :

case class Cat(name: String) 

val t = test[Cat].method 

pojawia się następujący błąd:

method method in class Test cannot be accessed in Test 
val t = test[Cat].method 
       ^

Moim nadrzędnym celem jest wykorzystanie vampire methods i użyć quasi-cudzysłowu do opisania wygenerowanej klasy. Jak mogę rozwiązać ten błąd?

+0

Czy twoja zsyntetyzowana klasa nie może rozszerzyć cechy, która abstrakcyjnie definiuje "metodę"? –

+0

Nie, ponieważ muszę generować te metody o określonych nazwach. Próbując to zrobić, zdałem sobie sprawę, że nie mam dostępu do nie generowanych metod. Podejrzewam, że nie używam tu poprawnie quasi-cytatów. – Eric

+0

Nie miałem pojęcia, że ​​istnieje teraz wtyczka kompilatora dla makrowego raju (w przeciwieństwie do bycia zmuszonym do używania rozwidlonego kompilatora). Jeśli chcesz się tego nauczyć, bardzo dziękuję za twoje pytanie. –

Odpowiedz

10

W moim poście na temat metod wampirycznych wspomnę o this workaround dla this bug. Z jakiegoś powodu obecnie nie można zobaczyć metod anonimowej klasy na instancji zwróconej z makra, chyba że utworzysz klasę opakowania, która rozszerzy klasę o metody i zwróci instancję tego.

Widzisz ten sam błąd z nieco innej perspektywy. Nazwałeś klasę metodami, które chcesz zobaczyć na strukturalnym typie zwróconej instancji, ale nadal potrzebujesz opakowania. Następujące będzie działać:

c.Expr { q""" 
    class $className { 
     def method = 1 
    } 
    new $className {} 
    """} 

Zauważ, że wszystko robiłem jest dodać parę wsporników do linii tworząc instancję, tak aby uzyskać instancję anonimowej klasy rozciągającej $className zamiast tylko $className.

Nie mam pojęcia, co kryje się za tym błędem, i nie jestem pewien, czy Eugene wie więcej. Niedawno potwierdziłem, że nadal jest w najnowszej wersji 2.11.

+1

Przedstawię to na następnym spotkaniu refleksyjnym. –

+1

Wiedziałem, że wkroczysz do Travis. Dzięki! Teraz mogę przygotować następne pytanie :-) – Eric

+1

Wygląda na to, że jest zgodne z projektem. Według Martina, umożliwienie natychmiastowym członkom miejscowych klas skończyć się typami strukturalnymi doprowadziło wówczas do pewnych dziwnych problemów, dlatego teraz trzeba zrobić jeszcze więcej, aby odsłonić tych członków. –

Powiązane problemy