Was ist die empfohlene Methode, um die Ergebnisse von Makroberechnungen an die Laufzeit zu übergeben?

9

Ich versuche eine SQL-ähnliche Abstraktion zu erstellen und habe ein Problem gefunden.

Dies ist eine vereinfachte "Datenbanktabelle":

%Vor%

Dies ist meine Abfrage Abstraktion:

%Vor%

Dies ist meine Makroimplementierung:

%Vor%

Und das ist mein Beispielcode:

%Vor%

Es kompiliert und läuft gut, aber die Ausgabe ist:

%Vor%

Grundsätzlich scheint result leer zu sein. Ich erwartete, dass es die angesammelten Stränge der Bäume halten würde.

Wie kann ich meine Daten von der Macro-Compile-Phase zur nächsten Phase übertragen, sodass sie zur Laufzeit angezeigt wird? Ich könnte natürlich die aktuelle Zeichenfolge explizit an die nächste Methode übergeben, aber das möchte ich vermeiden.

    
soc 02.08.2012, 12:19
quelle

3 Antworten

3

Grundsätzlich müssen Sie eine Queryable -Abstraktion haben, die: 1) die Sammlungs-API ( from , select , usw.) bereitstellt, 2) sich die aufgerufenen Methoden merkt, indem sie die Aufrufe verdichtet und akkumuliert innen.

Dieses Konzept ist in unseren ScalaDays Folien [1] etwas erklärt und wird in Slick (Open Source) implementiert [2]. Übrigens machen sie in LINQ ungefähr das gleiche mit den Methoden auf Queryable , die die Aufrufe vereinheitlichen und sie Ihrem Objekt zuführen, das IQueryable implementiert, z. wie in [3] beschrieben.

Links:

  1. Ссылка
  2. Ссылка
  3. Ссылка
Eugene Burmako 02.08.2012, 15:06
quelle
2

Das Problem besteht nicht darin, die Informationen von einem Makroaufruf an den nächsten zu übergeben. All das geschieht zur Kompilierzeit, das sollte funktionieren. Das Problem ist mit dem Makro, das zuletzt aufgerufen wird. Da c.universe.reify(new Where(result.toString)) zurückgegeben wird, wird new Where(result.toString) zur Laufzeit aufgerufen. Und dann wird result leer sein. Was Sie tun können, ist c.Expr(tree) zurückzugeben, wobei tree den Konstruktor von Where auf ein String literal anwendet, das result.toString enthält.

Sie sollten auch beachten, dass Ihr Code von der Reihenfolge abhängt, in der die Makroaufrufe kompiliert werden. Wenn Sie in mehreren Codedateien mehrere Aufrufe dieser Makros ausführen, enthält result möglicherweise Informationen aus früheren Aufrufen. Es wäre wahrscheinlich am besten, den gesamten Ansatz zu überdenken.

    
Kim Stebel 02.08.2012 13:01
quelle
0

Wie @Kim darauf hinweist, dass die Aggregation der Informationen nicht das Problem ist, sondern dass die Makroerweiterung Code generiert, der result.toString zur Laufzeit auswertet, wenn er tatsächlich leer ist. Ich hatte ein ähnliches Problem wie Sie und tat das Äquivalent, indem ich result.toString durch resultExpr(c).splice

ersetzte %Vor%

(Wie @Kim auch darauf hinweist, wird dies die aufgelaufenen Ergebnisse aller Makroaufrufe an die Laufzeit zurückgeben, also Vorsicht!)

    
subsub 23.08.2012 10:21
quelle

Tags und Links