Ich habe über die Bibliotheken gelesen, die für Sprachen wie Java und C # geschrieben wurden, die das Weben von Bytecode verwenden, um beispielsweise Funktionsaufrufe abzufangen, Protokollcode einzufügen usw. Ich habe auch über Lisp / Clojure-Makros in einem gelesen versuchen Sie besser zu verstehen, wie man sie benutzt. Je mehr ich über Makros lese, desto mehr scheint es, dass sie die gleiche Funktionalität bieten wie Bytecode-Webbibliotheken. Mit Funktionalität meine ich die Fähigkeit, Code zur Kompilierungszeit zu manipulieren.
Beispiele für Bibliotheken, die ich mir angesehen habe, sind AspectJ, PostSharp und Cecil.
Gibt es etwas, das mit dem einen und nicht mit dem anderen gemacht werden kann? Lösen sie tatsächlich die gleichen Probleme oder vergleiche ich Äpfel und Orangen?
quelle
Antworten:
Das Weben von Bytecodes und Makros sind zwei verschiedene Dinge.
Das Weben von Bytecode ist eine Möglichkeit, Funktionsaufrufe abzufangen, sodass Sie einem Funktionsaufruf vor oder nach der Ausführung der Funktion eine Art von Funktionalität (im Allgemeinen ein Querschnittsthema wie die Protokollierung) hinzufügen können. Das Weben von Bytecode erfolgt auf Bytecode-Ebene, was bedeutet, dass es nach der Kompilierung erfolgt. Die Funktion selbst ist nicht betroffen. Dies ist eine der Techniken, die bei der aspektorientierten Programmierung verwendet werden.
Makros sind eine Möglichkeit, die Syntax einer Sprache zu erweitern. In seiner einfachsten Form ist ein Makro einfach eine Möglichkeit, Tastenanschläge aufzuzeichnen und sie dann mit einem Hotkey wiederzugeben. Sprachmakros funktionieren auf ähnliche Weise. Ein Schlüsselwort oder ein anderes Syntaxkonstrukt ersetzt eine Art Makroerweiterung. Dies ist natürlich zu stark vereinfacht; Ein besseres Beispiel für ein für Lisp spezifisches Makro finden Sie hier .
quelle
Obwohl sie zum gleichen Zweck verwendet werden können, unterscheiden sich LISP-Makros erheblich von Java-Bytecode-Web-Plugins. LISP-Makros erweitern die LISP-Syntax auf der Ebene des LISP-Quellcodes. Da LISP-Makros auf derselben Ebene wie anderer LISP-Code geschrieben werden, sind sie eine häufig verwendete Sprachfunktion.
Java-Bytecode-Web-Plugins arbeiten auf JVM-Ebene. Während viele Java-Programmierer möglicherweise von anderen geschriebene Bytecode-Web-Plugins verwenden, schreiben nur sehr wenige Java-Programmierer ihre eigenen Bytecode-Web-Plugins.
Einige der von Java-Compiler-Plugins geleisteten Arbeiten lassen sich sehr einfach in dynamischen Sprachen ausführen. Das Abfangen von Funktionsaufrufen ist besonders einfach.
quelle
Lisp-Makros werden auf Quellcode-Ebene ausgeführt. Wenn Sie ein Makro um einen Code wickeln, können Sie viele Dinge tun. Einschließlich Parsen des Quellcodes, Einfügen von Code, Umschreiben von Code usw.
Wenn Sie Funktionsaufrufe ändern möchten, verwendet Lisp normalerweise zwei Mechanismen:
späte Bindungssymbole. Sie können die an ein Symbol gebundene Funktion ändern. Jeder Funktionsaufruf, der ein Symbol durchläuft, verwendet dann die neue Funktion.
Lisp-Implementierungen bieten manchmal eine Funktion, die als "Beratung" bezeichnet wird. Dies ermöglicht die Ausführung von Code vor, nach oder um Aufrufe. Zum Beispiel in LispWorks: Beratung .
Auf diese Weise können Sie Anrufe abfangen, ohne den Code auf niedriger Ebene zu manipulieren.
quelle