Clojure: Auflistung aller deftypes, die ein Protokoll im Namespace implementieren

8

Ich habe ein Protokoll und mehrere DefTypen, die es in einem Arbeitsbereich implementieren. Wie kann ich alle deftypes auflisten, die folgendes Protokoll implementieren?

Ich bin zu der Lösung gekommen, die Daten von (ns-public) filtert, aber ich mag sie nicht, weil sie etwas "Magie" benutzt, um die Arbeit zu erledigen, da ich keinen richtigen Weg gefunden habe erreiche mein Ziel mit erfüllt? und erweitert? .

Irgendwelche Ideen?

%Vor%     
ndrw 09.01.2013, 21:35
quelle

1 Antwort

1

Im Allgemeinen wird dies ein haariges Problem sein, das zu lösen ist, weil es zwei verschiedene Möglichkeiten gibt, wie ein Typ ein Protokoll erfüllen kann. Sie können jede vorhandene Java-Klasse mithilfe der Funktionen extend-type und extend-protocol zu einem Protokoll erweitern (dies ist eine sehr mächtige Funktion, da Sie Ihren Code so erweitern können, dass er mit integrierten Java- oder Clojure-Typen oder anderen Parteitypen, die du nicht kontrollierst). Oder Sie können eine Protokollimplementierung direkt als Teil einer Typdefinition in deftype oder defrecord angeben. Diese beiden Mechanismen sind unterschiedlich implementiert.

Der erste Fall (Erweiterung über extend-type oder extend-protocol ) wird für Sie leichter zu lösen sein, da der erweiterte Typ an das Protokoll selbst angehängt wird (ein Protokoll entspricht im Wesentlichen einer generierten Java-Schnittstelle) plus eine Clojure-Map mit Metadaten zum Protokoll). Sie können die Typen finden, die das Protokoll erweitern, indem Sie den Schlüssel :impls in der Protokollzuordnung anzeigen:

%Vor%

Der zweite Fall (direktes Implementieren eines Protokolls über deftype oder defrecord ) ist schwieriger, da die für den Typ oder Datensatz generierte Java-Klasse die vom Protokoll definierte Java-Schnittstelle direkt implementiert (Sie können implementieren jede Java-Schnittstelle in deftype oder defrecord , nicht nur ein Protokoll). Jede Herangehensweise, um Typen zu finden, die ein Protokoll auf diese Weise erweitern, wird ein gewisses Maß an Scannen und Reflektion erfordern. Im Wesentlichen fragen Sie: "Wie kann ich alle Java-Klassen finden, die eine bestimmte Schnittstelle implementieren?"

In einer typischen Java-Anwendung könnten Sie etwas tun, um die Verzeichnisse des Klassenpfads nach .class-Dateien zu durchsuchen und nach ihnen zu schauen, aber das funktioniert in Clojure nicht, weil es sehr wohl keine .class-Dateien sind für Ihre Typen (der Bytecode wird dynamisch generiert). Wenn Sie nicht mit Ihrer eigenen Implementierung zufrieden sind, können Sie die Antwort in dieser Frage überprüfen und sehen, ob es mehr nach Ihrem Geschmack ist:

Suchen Sie nach Java-Klassen, die eine Schnittstelle implementieren

    
Alex 10.01.2013, 15:55
quelle

Tags und Links