Nachdem ich das Buch The Pragmatic Programmer gelesen hatte , war eines der interessantesten Argumente "Code schreiben, der Code schreibt".
Ich habe versucht, im Internet nach weiteren Erklärungen oder Artikeln zu suchen, und obwohl ich einige gute Artikel zu diesem Thema gefunden habe, habe ich immer noch keine spezifische Code-Implementierung oder gute Beispiele gefunden.
Ich denke, es ist immer noch kein so verbreitetes Argument, etwas, das nicht dokumentiert ist oder von so vielen Leuten nicht angenommen wird, und ich würde gerne mehr darüber erfahren.
Was denkst du über das Thema? Ist es etwas, das Ihre Produktivität wirklich steigern wird? Was sind einige gute Ressourcen zu diesem Thema, darunter Bücher, Blogs, Diashows usw.?
Einige Codebeispiele würden mich sehr freuen, wenn ich deren Implementierung besser verstehen könnte.
Hier ist die Wiki-Seite zum Thema mit verschiedenen relevanten Programmiertechniken, wie Metaprogrammierung, generative Programmierung und Codegenerierung.
quelle
Antworten:
In der Lisp-Welt ist es durchaus üblich, den Code zu sehen, der Code schreibt, der Code schreibt (und so weiter). Jedes anständige Lisp- oder Scheme-Projekt ist also ein gutes Codebeispiel. Ich würde empfehlen, sich den Racket- Compiler und die Laufzeitquellen sowie Bigloo anzuschauen , deren Bibliotheken einfach brillant sind.
Produktivität: Ich verwende in fast allen meiner Entwicklungsarbeiten die Metaprogrammierung als vorherrschende Technik, und sie hilft eindeutig sehr, da sie sowohl die Codegröße verringert als auch die Lesbarkeit erhöht. Der Schlüssel liegt in der Verwendung domänenspezifischer Sprachen , und die Metaprogrammierung ist eine der effizientesten Möglichkeiten, diese zu implementieren.
quelle
Ich gehe lieber ein bisschen weiter und anstatt Code zu schreiben, der Code schreibt , schreibe ich Code, der Objekte, Methoden und Funktionen generiert. Dies kann beispielsweise mit Lisp-Makros oder dynamischen Ruby-Programmmodifikationsfunktionen erreicht werden.
Der kleine Unterschied ist, dass Sie nicht mit automatisch generierten Quelldateien enden. Normalerweise sind diese Dateien nicht lesbar und können nicht geändert werden. Warum sollten Sie sich also damit beschäftigen? Ich mag es nicht, meine Codebasis mit etwas zu vergrößern, das ich nicht kontrollieren kann.
Ein Buch, das ich gerne zu diesem Thema las, war Metaprogramming Ruby (wenn Sie die Ruby-Sprache beherrschen ).
Bearbeiten Sie nach der folgenden Frage im Kommentar:
Erstens ist die Metaprogrammierung kein Ziel, sondern ein Werkzeug. Verwenden Sie keine Metaprogrammierung, weil "es ist cool" oder "X sagte, jeder Entwickler sollte es verwenden".
Ich denke, ein guter Grund für die Verwendung der Metaprogrammierung besteht darin, ein allgemeines Muster (Muster als Wiederholung) zu verallgemeinern, das Sie in Ihrem Code gefunden haben und das mit keiner anderen üblichen Programmiertechnik (Vererbung, Entwurfsmuster usw.) erreicht werden kann.
Wie Jordan sagte , ist ein typischer Anwendungsfall das Datenbankhandling und ORM (Object Relation Mapping). In Ruby sollten Sie sich noch einmal ActiveRecord ansehen , das ein hervorragendes Beispiel für die auf ORM angewendete Metaprogrammierung ist.
Als letzte Anmerkung:
Denken Sie nicht "Ich möchte die Metaprogrammierung anwenden, wo könnte ich sie in meinem Code anwenden?".
Denken Sie "Ich sehe dieses Muster, das sich im gesamten Code wiederholt. Ich kann keinen Weg finden, den Code in etwas Kleineres und Wiederverwendbareres umzugestalten. Vielleicht kann mir die Metaprogrammierung helfen?"
quelle
Verwenden Sie noch besser den Code, den jemand anderes geschrieben hat und der Ihren Code für Sie schreibt.
Die Code-Automatisierung eignet sich im Allgemeinen für ORMs und anderen Datenbank-Interaktionscode und natürlich für die wiederholte, aber ähnliche Code-Erstellung.
Natürlich, wenn Sie viele ähnlich aussehende Klassen aufbauen, hätten Sie vielleicht das Gleiche in einer dynamischen Sprache viel früher erreichen können, aber ich schweife ab.
Dies wird von vielen Menschen begrüßt, obwohl die Software häufig als Codegeneratoren bezeichnet wird.
Sehen Sie sich Unternehmen und Produkte wie CodeSmith und MyGeneration an oder stöbern Sie in diesem Wikipedia-Artikel: http://en.wikipedia.org/wiki/Comparison_of_code_generation_tools
quelle
Eines der klassischen Beispiele ist Lex und Yacc. Ihr Hauptzweck ist es, die Plackerei beim Schreiben jeglicher Art von Parser zu vermeiden. Auf dem Weg dorthin können komplexe Parser mit vielen Regeln und Zuständen viel schneller erstellt werden, und es werden auch alle Überraschungsfehler vermieden, die von Leuten begangen werden, die ihre eigenen machen.
Dies ist auch die Idee hinter c, einem Tool zum Schreiben von Assemblern. Das Gleiche gilt für jede höhere Sprache, die Sie benennen möchten. Für Tools, die Code für Sie schreiben, gibt es einige einfache Paradigmen.
Eine ordnungsgemäße IDE hilft, indem sie Dokumentation, intelligente automatische Vervollständigung und Codefragmente zur Hand gibt. Die IDEs enthalten auch verschiedene Vorlagen, sodass Sie ein Programm nicht von Grund auf neu starten müssen. Es gibt Programme, um ein UML-Diagramm zu erstellen und Klassen in einer höheren Sprache aufzubereiten.
Schließlich können Sie Ihre eigenen Tools für die Codegenerierung innerhalb Ihres Problemsets schreiben. So haben Lex und Yacc angefangen. Aus genau diesem Grund gibt es jede Art von domänenspezifischer Sprache. Sie erstellen einige Bausteine, die Ihre Lösung in einfacher verständlichem Code beschreiben, und fassen allgemeine Aktivitäten oder komplizierte Abschnitte mit einfachen Befehlen zusammen. Sie suchen nicht für jedes Problem eine Lösung, sondern eine einfachere Definition des konkreten Problems, mit dem Sie sich befassen.
In gewisser Weise ist alles, was Sie über der Binärschicht tun, Code-Automatisierung.
quelle
Metaprogrammierung
Metaprogrammierung ist in vielen Geschäften eine umstrittene Technik. Der Grund dafür ist, wie bei jedem leistungsfähigen Werkzeug, die Größe der Hilfe oder des Schmerzes groß.
Vorteile
Nachteile
Ich bin ein großer Fan von Metaprogrammierung, aber ich mache das schon lange. Für mich macht der Kompromiss zwischen reduzierter Codegröße und konsistentem Verhalten die Risiken mehr als wett. Weniger Code bedeutet weniger Fehler, weniger Code, der gewartet werden muss, und ich kann normalerweise sehr schnell umfangreiche Funktionen hinzufügen.
Dies bedeutet jedoch nicht, dass ich denke, dass sich alle Programmierer damit befassen sollten. Ich habe große Probleme gesehen und musste sie beheben, die durch Metaprogrammierung entstanden sind. In der Regel von Personen, die das Konzept nicht verstehen und versucht haben, die Funktionalität zu erweitern oder nur einen Fehler zu beheben. Es braucht eine bestimmte Denkweise, die zumindest detailorientiert ist. Die Frage zur Verwendung von Metaprogrammiertechniken sollte eine Teamentscheidung sein . Wenn Sie Teammitglieder haben, die nicht verstehen, nicht das Temperament dafür haben oder einfach dagegen sind, sollte kein Teammitglied Metaprogramme verwenden.
quelle
Der meiste Code schreibt Code. Zum Beispiel hilft PHP-Code beim Schreiben von HTML. Die PHP-PDO-Bibliothek hilft beim Schreiben von SQL-Aufrufen. Die Datei-E / A-Funktionen schreiben Code für die Kommunikation mit dem Betriebssystem. Sogar ein regulärer Funktionsaufruf ist ein Verweis auf einen anderen Codeblock, der ausgeführt wird. Ihre Funktionsaufrufe schreiben also Code.
Allgemein können wir uns das Schreiben von Codes vorstellen, die rekursiv Codes schreiben und einen Stapel bilden, der endet, wenn er gegen die physikalische Realität von in Hardware verkabelten Codes stößt.
quelle
Wie Sie dies tun, hängt von Ihren Anforderungen ab. Angenommen, Sie verwenden die statische Codegenerierung, können Sie die gesamte Infrastruktur selbst schreiben oder einen vorhandenen Generator wie CodeSmith oder MyGeneration verwenden. Mit diesen müssen Sie nur die erforderlichen Vorlagen schreiben.
Mein letztes Projekt, das dies betraf, waren einige grundlegende ASP.NET CRUD-Bildschirme (die Codegenerierung ist hierfür gut geeignet). Der Prozess ging Entitäten als Metadaten in XML-Dateien definieren. Schreiben Sie Vorlagen, um die verschiedenen erforderlichen Artefakte abzudecken (Entitätsklassen, Repositorys, Serviceklassen, asp.net-Steuerelemente, asp.net-Seiten usw.). Führen Sie den Generierungsprozess aus und gestalten Sie die Ausgabe.
Das Schreiben der Vorlagen ist mit einem gewissen Aufwand verbunden, kann jedoch für nachfolgende ähnliche Projekte wiederverwendet werden. In ähnlicher Weise werden Änderungen an den zugrunde liegenden Daten behandelt, indem die Metadaten geändert und die Generierung erneut ausgeführt wird, wodurch Änderungen einfacher und schneller implementiert werden können.
Wie zum Testen. Da es sich um ein Templat-System handelt, müssen Sie zunächst einige Zeit damit verbringen, die Ausgabe des Prozesses zu validieren. Wenn Ihre Vorlage falsch ist, ist die gesamte Ausgabe dieser Vorlage in ähnlicher Weise falsch. Wenn Sie damit zufrieden sind, können Sie mit den Codegeneratoren auch grundlegende Tests aus den XML-Metadaten erstellen, die Sie dann erweitern können, um Sonderfälle abzudecken. Denken Sie jedoch daran, dass Sie möglicherweise immer noch Code-Tests durchführen müssen, um bestimmte Dinge zu berücksichtigen. Die Code-Generierung reduziert Ihre Arbeit und beseitigt sie nicht vollständig.
quelle
In unserem Unternehmen verwenden wir einige Tools, die C ++ - oder C # -Klassen mit aus dem Internet heruntergeladenen Daten generieren. Diese Klassen sind Datencontainer und enthalten eine große Anzahl von Objekten in Listen.
quelle
Die Metaprogrammierung ist seit langem Teil der Programmierung. Betrachten Sie nicht nur Tools wie SWIG oder WYSIWYG-Designer, die Code erstellen, sondern auch Tools in Sprache wie Cs Präprozessor oder sogar C ++ - Vorlagen und C # / Java-Generika - ganz zu schweigen von Reflection.
Tatsächlich könnte man argumentieren, dass jeder Compiler nur ein anderes Metaprogramm ist - er nimmt Programmtext und Ausgabemaschinen- oder VM-Code auf. Und Leben ohne Compiler? Owch.
quelle
Hier ist ein konkretes Beispiel aus meiner Vergangenheit.
Ich arbeitete an einer Site mit etwa 50 MB Delphi-Quellcode, der die BDE für den Datenzugriff verwendete. Sie wollten zu Direct Oracle Access wechseln, um ein Oracle-Upgrade über die höchste von der BDE unterstützte Version hinaus zu ermöglichen (8i, wenn ich mich richtig erinnere).
Anstatt ein Team von Programmierern zu veranlassen, alle Formulare und Datenmodule manuell zu ändern, habe ich ein PERL-Skript geschrieben, das:
Analysierte das DFM (Formulardatei) und identifizierte alle TQuery-, TTable-, TStoredProcedure- und TDatabase-Objekte, wobei die Elemente in einer Liste gespeichert wurden.
Analysierte den PAS (Code) und identifizierte die Verwendung der Objekte - führten die TQueries Aktualisierungen oder Auswahlen durch? Außerdem wurden alle Objekte identifiziert, die im Code erstellt wurden, anstatt in der IDE auf einem Formular abgelegt zu werden.
DFM & PAS wurden umgeschrieben, und die Objekttypen wurden entsprechend geändert (z. B. TTable -> TOracleDataSet, wobei die SQL-Eigenschaft auf "select * from" usw. gesetzt war) und die Methodenaufrufe wurden durchgeführt. Gegebenenfalls wurden zusätzliche Methodenaufrufe hinzugefügt, um Parameter zu schließen, zu öffnen und festzulegen.
Kurz gesagt, 3 Wochen Arbeit, um das Skript an verschiedenen Anwendungen zu optimieren, die von verschiedenen Teams mit unterschiedlichen Codierungsstilen geschrieben wurden, anstatt der ursprünglichen Schätzung, dass mehr als 5 Entwickler 6 Monate lang arbeiten.
Und der Grund, warum ich überhaupt daran gedacht habe, diesen Ansatz zu verwenden, war das Lesen von The Pragmatic Programmer
quelle
Sie fragen nach Beispielen ....
Wenn Sie mit SQL arbeiten, sollten Sie die Datenbank nicht direkt ändern, sondern Skripts ausführen, die die gewünschten Änderungen vornehmen, einschließlich struktureller Änderungen an der Datenbank (Hinzufügen von Tabellen, Spalten, Primärschlüsseln, Einschränkungen usw.). . Häufig müssen Sie dieselbe Aktion für viele Tabellen oder Spalten gleichzeitig ausführen, und es wäre mühsam, sie einzeln auszuführen. Ein kurzes Skript, das ein größeres Skript ausgibt, das das tut, was Sie wollen, kann real sein Zeitersparnis.
Zum Beispiel, bevor der Datentyp DATE in MS SQL Server eingeführt wurde, war die einzige Wahl für eine Datumsspalte DATETIME, die einen Zeitteil hat - einen Zeitteil, der den Umgang mit den Daten etwas erschwert. Nach dem Upgrade auf eine Version mit dem Datentyp Datum möchten Sie möglicherweise die Spalten aktualisieren, bei denen die Uhrzeit immer 00:00 Uhr ist. In einer Datenbank mit Dutzenden oder sogar Hunderten von DateTime-Spalten wäre dies recht zeitaufwändig. Es ist jedoch einfach, ein Skript zu schreiben, das alle Tabellen abfragt, wobei jede Spalte mit dem Datentyp DATETIME überprüft wird, um festzustellen, ob es jemals eine andere Zeit als 00:00 Uhr gibt, und wenn dies nicht der Fall ist, eine ALTER-Anweisung für die zu ändernde Tabelle / Spalte zu erstellen der Datentyp auf DATE. Presto, Code, der Code schreibt.
quelle
Schauen Sie sich die CL-Makros (Common Lips) an. Meiner Meinung nach ist das genau das, was Sie wollen. Lippen sind perfekt für die Metaprogrammierung.
Außerdem empfehle ich Nemerle, wenn Sie .NET-Fähigkeiten mit perfekter Metaprogrammierungsunterstützung (einschließlich Makros) haben möchten.
Aber wenn Sie eine echte Code-Generierungs-Engine wollen, schauen Sie sich Apache Thrift an
quelle
Ich arbeite gerade an einem solchen Tool. In unserem speziellen Fall generieren wir den VB.NET-Code basierend auf den Signaturen der Funktionen in der Datenbank für die Datenschicht.
Es ist zunächst schwierig, mit der Codegenerierung zu beginnen, da Sie keine Ahnung haben, wie der Code generiert werden soll. Wenn Sie jedoch über einen festgelegten Satz von Regeln verfügen und der zu generierende Code immer auf der Grundlage dieser Regeln generiert werden kann Das Arbeiten mit diesem Code ist nicht so schwierig. Abhängig von der Komplexität der Codegenerierung und der Anzahl der Regeln kann die Aufgabe natürlich schwieriger werden. Im Wesentlichen wird die automatische Codegenerierung jedoch für sich wiederholende Codierungsaufgaben verwendet und nicht für erweiterten Code, der sehr unterschiedlich ist.
Es gibt zwei Möglichkeiten, die Ausgabe zu testen. Zuerst müssen Sie sicherstellen, dass der Code kompiliert wird, und das ist einfach. Dann müssen Sie sicherstellen, dass die Ausgabe auf der Grundlage der Parameter, mit denen sie generiert wurde, genau das tut, was Sie beabsichtigt haben. Die Schwierigkeit hängt von der Komplexität des von Ihnen generierten Codes ab.
Meine aufrichtige Empfehlung lautet, dass Sie sich die Zeit leisten können , wenn Sie das Gefühl haben, Code wiederholt zu schreiben . Versuchen Sie zu überlegen, ob das, was Sie tun, nicht durch generierten Code erreicht werden kann. Und wenn ja (wenn es sich um sich wiederholenden Code handelt, der fast immer der Fall ist), überlegen Sie, wie oft Sie diesen Code erweitern, leicht ändern und wie oft Sie genau diesen Code schreiben müssen. Wenn die Antwort auf eine dieser Fragen "viele" ist , sollten Sie ernsthaft in Betracht ziehen, einen Generator für diesen Code zu erstellen .
Hoffe das hilft,
IPP
quelle
Ich habe ein PHP-Modul, das eine Webseite ausgibt, die JavaScript-Code enthält, der HTML generiert. Das sind genau dort drei Schichten. Junge war so schwer zu lesen!
In einer Programmierklasse mussten wir ein Programm schreiben, das dem Benutzer eine Formelzeichenfolge entnimmt, diese analysiert und den Wert anzeigt. Der eindrucksvollste Löser hat einfach die Benutzereingaben übernommen, in main () {printf ("% d", ...);} eingeschlossen und ein Skript zum Kompilieren, Verknüpfen und Ausführen ausgeführt. Er hat keinen Parser geschrieben! Heute könnten Sie das in einer SQL SELECT-Anweisung tun.
Es ist ein Werkzeug, mit dem Sie spielen und es dann für einen zukünftigen Tag aufbewahren sollten, wenn es nützlich sein wird.
quelle
Ich habe mit Prolog nette Meta-Programmierlösungen entwickelt . Wobei die Hauptanwendung (in C ++ etwa) eine abstrakte Definition eines Problems zur Laufzeit in eine Prolog-Anwendung übersetzt, die dann an delegiert wird. Häufig dauerte es ewig, äquivalente Funktionen in C ++ zu schreiben.
Ich denke, dieses Szenario ist ein ausgezeichneter Fall für das Argument Code-Schreiben-Code .
quelle
Was denkst du über das Thema?
Die Metaprogrammierung wird am häufigsten mit nicht dynamischen Sprachen in Verbindung gebracht, da es schwieriger ist, bestimmte Verhaltensweisen (z. B. die Implementierung eines ORM) ohne viele unproduktive und nicht intelligente Codezeilen zu erreichen.
Aber auch in dynamischeren Sprachen wie PHP kann die Codegenerierung wirklich lebensrettend sein und die Produktivität enorm steigern. In modernen Frameworks ist es sehr verbreitet, ein Gerüst zu haben, das die meisten gängigen Modelle, Formen, Tests und Aktionen für ein bestimmtes Geschäftsobjekt generiert, das Sie deklarieren. Dies ist einer der Gründe, warum Frameworks wie Symfony oder RoR so erfolgreich sind, dass diese Tools zur Codegenerierung sehr schnell konsistenten Code erstellen und die Produktivität des Programmierers steigern.
Auf Websites dreht sich der Großteil der Interaktion um vier Hauptaktionen:
Zumindest alles, was sich um diese 4 Hauptaktionen dreht, könnte und sollte IMHO mit Code-Generierungs-Tools erreicht werden, um maximale Produktivität zu erzielen.
In meinem Unternehmen verwenden wir symfony, und der Admin-Generator ist ein außergewöhnliches Tool, das sogar Code zur Laufzeit generiert (und zwischenspeichert), was bedeutet, dass wir dazu nicht einmal irgendeine Aufgabe oder ein externes Tool verwenden müssen Um neuen Code zu generieren, müssen wir nur unseren Cache bereinigen. Ich rate dringend, diese Art von Tool für CRUD-Operationen zu verwenden.
Aber es ist keine leichte Aufgabe, das zu tun, was symfony großartige Mitwirkende getan haben. Ich habe einige Code-Generierungsaufgaben selbst implementiert und es ist nicht einfach, etwas zu tun, das wirklich konsistent ist und mit einer breiten Implementierung die meisten Eckfälle abdeckt.
Ist es etwas, das Ihre Produktivität wirklich steigern wird?
Ich glaube, dass Metaprogrammierung in niedrigeren Arbeitsebenen (Frameworks, Caching, Compiler usw.) sehr wichtig ist, aber etwas, das wir mit äußerster Vorsicht angehen müssen, wenn wir Dinge auf der Business-Ebene tun.
Die Verwendung von Code-Generierung ist ohne Frage ein großer Produktivitätsschub. Implementieren Sie Ihre eigenen Tools zur Codegenerierung, nicht so sehr, es sei denn, Sie erstellen selbst ein Framework.
Was sind einige gute Ressourcen zu diesem Thema, darunter Bücher, Blogs, Diashows usw.?
Die beste Quelle, um die Programmierung zu verstehen, ist immer guter und gut kommentierter Quellcode. Ich würde sagen, dass ein Blick in RubyOnRails und Symfony- Administratoren eine gute Idee ist.
quelle
Während sich viele Antworten hier auf das beziehen, was allgemein als Metaprogrammierung bekannt ist, gab es tatsächlich ein mit AI verbundenes Feld, das als automatische Programmierung bekannt ist und sich mit dem Verstehen oder Synthetisieren von Programmen befasst [1].
Jeder Compiler (oder Metaprogramm, Codegenerator, Übersetzer, Makrosystem, ...) arbeitet mit Transformationen und generiert aus einer Eingabe eine Ausgabe, indem er seinen festen Transformationsalgorithmus ausführt. Ein herkömmlicher Compiler oder ein herkömmliches Metaprogramm erstellt jedoch angesichts einer Definition, Beschreibung oder eines Beispiels für das Sortieren einer Liste (z. B. [5, 3, 9] => [3,5,9]) keinen Sortieralgorithmus. Solche Probleme waren von Interesse für dieses "automatische Programmieren".
[1] - Fortschrittsbericht zu Systemen für das Programmverständnis ftp://db.stanford.edu/pub/cstr/reports/cs/.../CS-TR-74-444.pdfShare
quelle
Meta-Programmierung kann sehr schwierig zu pflegen sein. Am Anfang sieht es elegant aus, aber wenn Sie anfangen, auf Eckfälle zu stoßen, werden die Fehler zu spät abgefangen (auf dem Code, der generiert wurde), und das Ganze wird zu einem Albtraum, den Sie benutzen / debuggen müssen.
Ich habe hauptsächlich Python-Code geschrieben und meiner Erfahrung nach ist Meta-Programmierung in dieser Sprache immer eine schlechte Wahl. Sie können Dinge, die Sie mit langweiligen normalen Sprachfunktionen erledigen möchten, jederzeit umgestalten. Das Ergebnis ist weniger funky, aber einfacher zu leben.
quelle
OP fragt nach Ressourcen.
Sie könnten unser DMS Software Reengineering Toolkit interessant finden. Es handelt sich um ein reines Metaprogrammierungswerkzeug, mit dem benutzerdefinierte Programmanalyse- und Transformationswerkzeuge erstellt werden können.
[Um einem Kommentar zur Frage von OP zu folgen, ist DMS bei der Erstellung eines bestimmten Transformationstools eine Produktlinie, die Code schreibt, der Code schreibt:]
DMS erreicht dies, indem es agnostisch (aber nicht unabhängig) von Zielprogrammiersprachen ist. DMS bietet die Standarddienste, die für eine Vielzahl von Metaprogrammierungsaufgaben erforderlich sind, ebenso wie ein Betriebssystem eine Vielzahl von Diensten für Standardprogrammierungsaufgaben bereitstellt. Diese Dienste umfassen starkes Parsen, automatisches Erstellen von Abstact-Syntaxbäumen, Musterabgleich und Umschreiben von Bäumen, Symboltabellenbibliotheken, mit denen Sprachen mit unangenehmen Bereichsregeln wie Mehrfachvererbung, Kontrollfluss, Datenfluss, Point-to- und Aufruf einfach verwaltet werden können Graph-Analyse. Nichts davon ist bedeutungslos, da keine spezifischen zu verarbeitenden Sprachen vorhanden sind. Daher akzeptiert DMS Sprachdefinitionen, die an diese allgemeinen Maschinen gebunden sind. Dies führt zu sprachspezifischem Parsing, AST-Konstruktion und zielsprachspezifischem Pattern Matching / Rewriting unter Verwendung der Zielsprache. Sprachsyntax,
Und wie ein Betriebssystem ist DMS so konzipiert, dass nur sehr wenige Meinungen oder Einschränkungen zu den (Meta-) Programmen bestehen, die Sie schreiben möchten. Dies bedeutet, dass es für eine Vielzahl von Zwecken verwendet werden kann: Extrahieren von Metriken, Auffinden von totem Code, Implementieren von Aspektwebern, Übersetzen Sprachen, Generieren von Codes aus DSLs, Neuarchitektur großer Anwendungen. (DMS wurde bereits für alle diese Aufgaben verwendet).
Man braucht robuste Sprachdefinitionen, wenn man nicht alles im Sprachreferenzhandbuch codieren möchte (überlegen Sie, was dies für Java und C ++ bedeutet). DMS löst dieses Problem, indem eine Bibliothek mit vollständigen Sprachdefinitionen zur Verfügung steht. Das Analoge hier ist wie eine Datenbank, die für Ihr Betriebssystem zur Verfügung steht. Sie müssen keinen von ihnen implementieren, um mit dem Schreiben Ihrer datenbankzentrierten Anwendung fortzufahren.
quelle
Siehe Philip Greenspuns Problemsatz 4 aus MIT-Kurs 6.916: Software-Engineering innovativer Webdienste ( http://philip.greenspun.com/teaching/psets/ps4/ps4.adp ).
Das Ziel lautet: "Bringen Sie den Schülern die Vorzüge von Metadaten bei. Insbesondere lernen sie, wie sie die Anforderungen eines Webdienstes formal darstellen und anschließend ein Computerprogramm erstellen, um die Computerprogramme zu generieren, die diesen Dienst implementieren."
Dies ist eines der Probleme, die potenzielle Rekruten von ArsDigita ( http://en.wikipedia.org/wiki/ArsDigita ) während der ersten Blase lösen mussten.
Das Buch "SQL für Web-Nerds", auf das Philip im pset verweist, wurde verschoben ( http://philip.greenspun.com/sql/ ).
quelle
Um das Jahr 2001 herum begann ich mit der Arbeit an einem Projekt, bei dem Geschäftsobjekte und Datenobjekte in großem Umfang genutzt wurden. Ich sollte die Front-End-Website erstellen, hatte aber das Problem, dass die Business-Schicht und die Datenzugriffsschicht nicht vollständig entwickelt waren. Nach ein paar Wochen begann ich mir genau anzuschauen, was diese Schichten taten. Grundsätzlich machten sie Daten, die von gespeicherten Prozeduren zurückgegeben wurden, als Auflistungen von Objekten mit Eigenschaften verfügbar, die den Feldern in den Daten entsprechen, oder nahmen Eingabeparameter und sendeten sie an gespeicherte Prozeduren, um sie in Datenbanktabellen zu speichern. Zwischen den beiden Ebenen fand eine Menge Serialisierung / Deserialisierung statt, es war Microsoft Transaction Server beteiligt, eine IDL / ODL-Typbibliothek ... aber alles passte zu einem Muster.
2 Wochen später ließ ich einen Codegenerator ausarbeiten, der IDL / ODL und auch die Geschäfts- und Datenobjekte löschte. Der Typ, der die Business- und Data-Layer-Objekte erstellt hatte, hatte 2 Jahre gebraucht, um diese Objekte zu debuggen und zu testen. In 2 Wochen hatten wir mit der Codegenerierung die gleiche Ausgabe, aber da alles generiert wurde, war es ziemlich fehlerfrei.
Dieser Codegenerator (untergeordnetes CASE-Tool) hat mich 8 bis 10 Jahre lang durch viele verschiedene Iterationen begleitet, weil das Prinzip so einfach war: Sie tun etwas, das getan werden muss, wenn Sie mit Datenbanken sprechen. Es ist hübsch viel repetitive Codierung, und sobald Sie es richtig gemacht haben, müssen Sie sich nicht mehr darum kümmern.
Also, ja: Verwenden Sie einen Codegenerator, insbesondere wenn sich die Codierung wiederholt und einem genau definierten Muster entspricht.
Ich kenne Leute, die RegX-Makros verwenden, um ähnliche Dinge zu tun, oder Excel-Formeln, um ähnliche Dinge zu tun (das mache ich auch).
quelle
Ein Beispiel für die Metaprogrammierung
Ich habe eine Ruby-Autorisierungsbibliothek namens Authority . Hier können Entwickler mit Methoden wie
current_user.can_read?(@post)
und Fragen in ihrer App stellen@post.readable_by?(current_user)
. Diese Fragen werden von zentralisierten Autorisierungsklassen beantwortet.Dies ist der entscheidende Teil: Die Behörde weiß nicht, welche Methoden zu definieren sind, bis sie die Konfiguration des Benutzers sieht . Die Benutzerkonfiguration kann enthalten:
In diesem Fall muss es eine Methode wie diese geben
current_user.can_microwave?(@post)
.Metaprogrammierung macht dies möglich: Nach dem Lesen der Konfiguration weiß ich, welche Methoden zu definieren sind :
quelle