Programmazione automatica: scrivere codice che scrive codice [chiuso]

104

Dopo aver letto il libro The Pragmatic Programmer , uno degli argomenti che ho trovato più interessanti è stato "scrivere codice che scrive codice ".

Ho provato a cercare in rete ulteriori spiegazioni o articoli su di esso, e mentre ho trovato alcuni buoni articoli sull'argomento, non ho ancora trovato alcuna implementazione di codice specifica o buoni esempi.

Ritengo che non sia ancora un argomento comune, qualcosa che manca di documentazione o che non è abbracciato da così tante persone, e mi piacerebbe saperne di più.

Che ne pensi dell'argomento? È qualcosa che aumenterà davvero la tua produttività? Quali sono alcune buone risorse in materia, tra libri, blog, presentazioni, ecc?

Alcuni esempi di codice sarebbero molto apprezzati per permettermi di capire meglio la sua implementazione.

Questa è la pagina wiki sull'argomento con varie tecniche di programmazione pertinenti, come Meta Programmazione, Programmazione generativa e Generazione di codice.

    
posta Jose Faeti 13.01.2012 - 03:42
fonte

22 risposte

47

Nel mondo Lisp, è abbastanza comune vedere il codice che scrive il codice che scrive il codice (e così via). Pertanto, qualsiasi progetto Lisp o Scheme di dimensioni decenti fungerà da buon esempio di codice. Ti consiglio di consultare il racket fonti di compilazione e di runtime, nonché Bigloo , le loro librerie sono semplicemente geniali.

Per quanto riguarda la produttività: sto utilizzando metaprogramming come tecnica dominante in quasi tutto il mio lavoro di sviluppo, e chiaramente aiuta molto, sia riducendo la dimensione del codice che aumentandone la leggibilità. La chiave sta nell'usare Lingue specifiche del dominio e la metaprogrammazione è uno dei modi più efficaci per implementarle.

    
risposta data 26.08.2011 - 11:39
fonte
67

Preferisco andare un po 'oltre e, invece di scrivere codice che scrive codice, scrivere codice che generi oggetti, metodi, funzioni. Ad esempio, è possibile ottenere macro Lisp o funzionalità di modifica dinamica del programma Ruby.

La piccola differenza è che non finisci con i file sorgente che sono stati generati automaticamente. Di solito questi file non sono leggibili dall'uomo e non possono essere modificati, quindi perché preoccuparsi di loro. Non mi piace l'idea di aumentare il mio codice base con qualcosa che non posso controllare.

Un libro che mi è piaciuto leggere sull'argomento era Metaprogramming Ruby (se conosci il linguaggio di Ruby)

Modifica dopo la seguente domanda nel commento:

Why should it be useful it I still have to code the generating code? Should I write a code able to generate different things depending on user input, so that I can reuse it over and over?

In primo luogo, metaprogramming non è un obiettivo, ma uno strumento. Non utilizzare metaprogramming perché "è cool" o "X ha detto che ogni sviluppatore dovrebbe usarlo".

Penso che una buona ragione per usare la metaprogrammazione sia quella di generalizzare alcuni pattern comuni (pattern come qualcosa che si ripete) che hai trovato nel tuo codice e che nessun'altra tecnica di programmazione usuale (ereditarietà, design pattern, ecc.) può raggiungere.

Come detto da Jordan , un tipico caso d'uso è la gestione del database e l'ORM (Object Relation Mapping). Ancora una volta, in Ruby, dovresti dare un'occhiata a ActiveRecord che è un ottimo esempio di metaprogrammazione applicata a ORM.

Come nota finale:

Non pensare "Voglio applicare metaprogramming, dove potrei applicarlo nel mio codice?".

Pensa "Vedo questo schema che si ripete su tutto il mio codice, non riesco a trovare un modo per ridefinire il codice in qualcosa di più piccolo e più riutilizzabile. Forse metaprogramming mi può aiutare? "

    
risposta data 12.04.2017 - 09:31
fonte
19

Ancora meglio, utilizza il codice scritto da qualcun altro che scrive il tuo codice per te.

L'automazione del codice è generalmente valida per gli ORM e altri codici di interazione del database e, naturalmente, per la creazione di codice ripetitiva ma simile.

Ovviamente, se stai creando molte classi dall'aspetto simile, forse avresti potuto realizzare la stessa cosa in un linguaggio dinamico molto prima, ma sto divagando.

Questo è accettato da molte persone, anche se spesso troverai il software etichettato come generatore di codice.

Guarda le aziende e i prodotti come CodeSmith e MyGeneration, oppure consulta questo articolo di Wikipedia: link

    
risposta data 26.08.2011 - 09:52
fonte
16

Uno degli esempi classici è lex e yacc. Il loro scopo principale è evitare la fatica di scrivere qualsiasi tipo di parser. Lungo la strada, rendono molto più veloce la creazione di parser complessi con molte regole e stati, ed evitano anche tutti gli errori a sorpresa compiuti da persone che ruotano da sole.

Questa è anche l'idea alla base di c, che è uno strumento per scrivere assemblatore. La stessa cosa vale per qualsiasi lingua di alto livello che ti interessa nominare. Per gli strumenti che scrivono il codice per te, ci sono alcuni semplici paradigmi.

Un IDE appropriato aiuta fornendo documentazione a portata di mano, completamento automatico intelligente e frammenti di codice. Gli IDE includono anche vari modelli, quindi non è necessario avviare un programma da zero. Ci sono programmi per fare un diagramma uml e classi grezzi in un linguaggio di alto livello.

Infine, puoi scrivere i tuoi strumenti per la generazione del codice all'interno del tuo set di problemi. Questo è il modo in cui lex e yacc sono stati avviati. Qualsiasi tipo di lingua specifica per dominio esiste proprio per questa ragione. È possibile creare alcuni elementi costitutivi che descrivono la soluzione in codice più semplice da comprendere, avvolgendo attività comuni o sezioni complesse con semplici comandi. Non stai cercando una soluzione al problema ogni , ma solo una definizione più semplice di quella specifica che stai trattando.

In un certo senso, tutto ciò che fai sopra il livello binario è l'automazione del codice.

    
risposta data 26.08.2011 - 14:50
fonte
13

Metaprogrammazione

Metaprogramming è una tecnica controversa in molti negozi. Il motivo è che, come qualsiasi strumento potente, l'entità dell'aiuto o del dolore è grande.

Pro

  • Più espressivo, meno codice da scrivere e mantenere (spesso di un ordine di grandezza o più)
  • Coerenza, comportamento più coerente sulla classe di problemi risolti con il codice
  • Produttività, meno codice per una soluzione in uno spazio di problemi più ampio

Contro

  • Complessità, può essere molto complicato anche se c'è meno codice
  • La sicurezza, a volte il tipo di sicurezza e l'analisi statica in generale saranno sacrificati
  • I bug influenzano di più, piccoli errori avranno un impatto maggiore

Sono un enorme fan della metaprogrammazione, ma lo sto facendo da molto tempo. Per me il compromesso tra dimensioni ridotte del codice e comportamenti coerenti compensa maggiormente i rischi. Meno codice significa meno bug, meno codice da mantenere e in genere posso aggiungere grandi quantità di funzionalità molto rapidamente.

Tuttavia, ciò non significa che tutti i programmatori dovrebbero impegnarsi in esso. Ho visto e ho dovuto risolvere i grossi problemi creati dalla metaprogrammazione. Di solito da quando le persone che non capiscono il concetto e hanno tentato di estendere la funzionalità, o semplicemente di correggere un bug. Ci vuole una mentalità particolare che sia per lo meno orientata ai dettagli. La domanda per utilizzare le tecniche di metaprogrammazione dovrebbe essere una decisione del team . Se hai membri del team che non capiscono, non hanno il temperamento per questo, o sono solo contro di esso nessuno della squadra dovrebbe usare metaprogramming.

    
risposta data 06.09.2011 - 07:04
fonte
9

La maggior parte del codice di scrittura del codice. Ad esempio il codice php aiuta a scrivere html. La libreria php pdo aiuta a scrivere le chiamate SQL. Le funzioni I / O di file scrivono il codice per comunicare con il sistema operativo. Anche una normale chiamata di funzione è un riferimento a un altro blocco di codice che viene eseguito. Quindi le tue chiamate di funzioni stanno scrivendo codice.

In termini generali, possiamo pensare al computing come a codici di scrittura che scrivono codici ricorsivamente formando uno stack che termina quando si scontra con la realtà fisica dei codici cablati nell'hardware.

    
risposta data 26.08.2011 - 19:26
fonte
5

Il modo in cui lo fai varia in base ai tuoi requisiti. Supponendo che si stia utilizzando la generazione di codice statico, è possibile scrivere da soli tutta l'infrastruttura oppure utilizzare un generatore esistente come CodeSmith o MyGeneration. Usando questi hai solo bisogno di scrivere i modelli richiesti.

Il mio ultimo progetto riguardante questo era alcune schermate ASP.NET CRUD di base (la generazione del codice è buona per questo). Il processo è andato a definire entità come metadati nei file xml. Scrivi modelli per coprire i vari artefatti richiesti (classi di entità, archivi, classi di servizio, controlli asp.net, pagine asp.net ecc.). Esegui il processo di generazione e definisci l'output.

C'è un sovraccarico nella scrittura dei modelli, ma possono essere riutilizzati per progetti simili successivi. Analogamente, le modifiche ai dati sottostanti vengono gestite modificando i metadati e rieseguendo la generazione, rendendo le modifiche più semplici e veloci da implementare.

Come per i test. Poiché si tratta di un sistema basato su modelli, è necessario dedicare un po 'di tempo alla convalida iniziale dell'output del processo, se il modello è sbagliato, tutti gli output di quel modello saranno ugualmente errati. Una volta che sei soddisfatto di questo, puoi anche utilizzare i generatori di codice per creare test di base dai metadati xml che puoi estendere per coprire casi speciali. Tuttavia ricorda che potresti avere ancora bisogno di test del codice mano per far fronte a cose specifiche, la generazione del codice riduce il tuo lavoro, non lo elimina del tutto.

    
risposta data 26.08.2011 - 11:36
fonte
5

Nella nostra azienda utilizziamo alcuni strumenti che generano effettivamente classi C ++ o C # con dati scaricati da Internet. Queste classi sono contenitori di dati e contengono un numero elevato di oggetti negli elenchi.

    
risposta data 26.08.2011 - 16:48
fonte
5

Metaprogramming ha fatto parte della programmazione per un lungo periodo. Prendi in considerazione non solo strumenti come i designer SWIG o WYSIWYG, che creano codice, ma anche strumenti in-house come il preprocessore di C, o anche i modelli di C ++ e i generici di C # / Java, per non parlare di Reflection.

In effetti, si potrebbe obiettare che ogni compilatore è solo un altro metaprogramma - prendono testo del programma e macchina di output o codice VM. E, vita senza compilatori? Owch.

    
risposta data 28.08.2011 - 12:10
fonte
5

Ecco un esempio concreto del mio passato.

Lavoravo in un sito che conteneva circa 50 MB di codice sorgente Delphi utilizzando BDE per l'accesso ai dati. Volevano passare all'uso di Direct Oracle Access per consentire a un aggiornamento di Oracle di superare la versione più alta supportata da BDE (8i se ricordo correttamente).

Quindi, invece di far lavorare una squadra di programmatori attraverso ogni modulo di moduli e dati modificando manualmente ogni componente, ho scritto uno script PERL che: -

  1. Analizzato il DFM (file di modulo) e identificato tutte le TQuery, TTable, TStoredProcedure & Oggetti TDatabase: archiviazione degli elementi in un elenco.

  2. Analizzato il PAS (codice) e identificato l'utilizzo degli oggetti - le TQuery stavano facendo aggiornamenti o selezioni? Inoltre, identificava qualsiasi oggetto creato nel codice piuttosto che lasciato cadere su un modulo nell'IDE.

  3. Riscrivi il DFM & PAS cambiando opportunamente i tipi di oggetto (ad esempio TTable - > TOracleDataSet con la proprietà SQL impostata su "select * from" ecc.) E le chiamate di metodo. Inoltre, se necessario, sono state aggiunte chiamate di metodo aggiuntive per chiudere, aprire & imposta i parametri.

In breve, 3 settimane di lavoro modificano lo script per lavorare su diverse applicazioni scritte da team diversi con stili di codifica diversi invece della stima originale di 5+ sviluppatori che lavorano per 6 mesi.

E la ragione per cui ho persino pensato di usare quell'approccio è stato leggendo The Pragmatic Programmer

    
risposta data 06.09.2011 - 07:33
fonte
4

Chiedi esempi ....

Quando si lavora con SQL, non si dovrebbe modificare direttamente il database, ma si suppone che stiano eseguendo script che eseguono qualsiasi modifica, comprese le modifiche strutturali al database (aggiungendo tabelle, colonne, chiavi primarie, vincoli e così via). Molto spesso devi fare la stessa azione contro un sacco di tavoli o colonne allo stesso tempo, e farli uno per uno sarebbe noioso, uno script breve che genera uno script più grande che fa quello che vuoi può essere un vero risparmio di tempo.

Ad esempio, prima che il tipo di dati DATE fosse introdotto in MS SQl Server, l'unica scelta per una colonna di date era DATETIME che ha una parte temporale, una parte temporale che rende più difficile trattare i dati. Dopo l'aggiornamento a una versione con il tipo di dati Date, è possibile aggiornare le colonne in cui l'ora è sempre 00:00. In un database con dozzine o centinaia di colonne DateTime, ciò richiederebbe molto tempo. Ma è facile scrivere uno script che interroghi tutte le tabelle, controllando ogni colonna con un tipo di dati di DATETIME per vedere se l'ora è sempre diversa da 00:00 e se non si crea un'istruzione ALTER per la tabella / colonna da cambiare il tipo di dati a DATA. Presto, codice che scrive il codice.

    
risposta data 10.08.2012 - 20:32
fonte
3

Dai un'occhiata alle macro CL (Common Lips). Secondo me è esattamente quello che vuoi. Le labbra sono perfette in metaprogrammazione.

Inoltre suggerisco Nemerle se vuoi avere i poteri di .NET con il perfetto supporto per Metaprogrammazione (incluse le macro)

Ma se vuoi che un vero motore di generazione del codice dia un'occhiata a parsimonia Apache

    
risposta data 29.08.2011 - 10:27
fonte
3

Sto solo lavorando a uno strumento del genere. Nel nostro caso specifico generiamo il codice VB.NET basato per il livello dati sulle firme delle funzioni nel database.

Iniziare a lavorare e con la generazione del codice è difficile all'inizio poiché non hai idea di come debba essere generato il codice, ma una volta che hai stabilito un insieme di regole e il codice che deve essere generato può sempre essere generato sulla base di quelle regole, lavorare con quel codice non è poi così difficile. Naturalmente, a seconda della complessità della generazione del codice e del numero di regole, l'attività può diventare più difficile. Ma in sostanza, la generazione automatica del codice viene utilizzata per attività di codifica ripetitive e non per codice avanzato che varia molto.

Test l'output è duplice. Per prima cosa devi assicurarti che il codice venga compilato, e questo è facile. Quindi devi assicurarti che l'output faccia ciò che intendevi fare in base ai parametri su cui è stato generato e la cui difficoltà varia a seconda della complessità del codice generato.

La mia raccomandazione sincera è che se ti senti come se scrivessi codice in modo ripetitivo , e ti puoi permettere il tempo .. Prova a pensare se ciò che stai facendo non può essere fatto generando codice. E se è così (se è un codice ripetitivo che è quasi sempre il caso) pensa quante volte dovrai estendere, modificare leggermente quel codice e anche quante volte devi scrivere quel tipo esatto di codice. Se la risposta a uno di questi è "molti", allora dovresti prendere seriamente in considerazione la possibilità di creare un generatore per quel codice .

Spero che questo aiuti,
IPP

    
risposta data 29.08.2011 - 12:27
fonte
3

Ho un modulo PHP che emette una pagina web contenente codice JavaScript che genera HTML. Sono tre strati proprio lì. Boy era così difficile da leggere!

In una classe di programmazione, dovevamo scrivere un programma che prendesse una stringa di formula da parte dell'utente e la analizzasse e visualizzasse il valore. Il solver più impressionante ha semplicemente preso l'input dell'utente, lo ha avvolto in main () {printf ("% d", ...);} e ha eseguito uno script per compilarlo, collegarlo ed eseguirlo. Non ha scritto un parser! Oggi puoi farlo in una istruzione SQL SELECT.

È uno strumento con cui dovresti giocare, quindi memorizzalo per qualche giorno futuro quando sarà utile.

    
risposta data 06.09.2011 - 11:07
fonte
3

Ho sviluppato delle soluzioni metaprogrammazione con Prolog . Dove l'applicazione principale (in C ++ dire) traduce una definizione astratta di un problema in un'applicazione Prolog in fase di esecuzione, a cui viene poi delegata. Spesso scrivere funzionalità equivalenti in C ++ richiederebbe sempre.

Penso che questo scenario sia un eccellente caso a favore dell'argomento code-writing-code .

    
risposta data 06.09.2011 - 14:35
fonte
3

Cosa ne pensi dell'oggetto?

La metaprogrammazione è più comunemente associata a linguaggi non dinamici, poiché è più difficile ottenere determinati comportamenti (come l'implementazione di un ORM) senza molte linee di codice non produttive e non intelligenti.

Ma anche in linguaggi più dinamici come PHP, la generazione del codice può essere davvero un salvavita e aumentare la produttività in grande quantità. Nei framework moderni è molto comune disporre di uno scaffolding che genera la maggior parte del modello, della forma, del test e delle azioni comuni per un determinato oggetto di business che dichiari. È uno dei motivi per cui framework come symfony o RoR hanno così tanto successo, quegli strumenti di generazione del codice rendono il codice coerente molto rapidamente e aumentano la produttività dei programmatori.

Nei siti web, la maggior parte dell'interazione ruota intorno a quattro azioni principali:

  • Crea un elemento
  • Recupera un insieme di elementi (con possibili filtri)
  • Aggiorna un elemento con nuovi attributi
  • Elimina un set di elementi

Almeno tutto ciò che ruota attorno a queste 4 azioni principali potrebbe e IMHO DOVREBBE essere raggiunto utilizzando strumenti di generazione del codice per ottenere la massima produttività.

Nella mia azienda, usiamo symfony e il suo admin-generator è uno strumento eccezionale, che genera anche codice in fase di esecuzione (e lo memorizza nella cache), il che significa che non abbiamo nemmeno bisogno di utilizzare alcun tipo di attività o strumento esterno per generare nuovo codice, abbiamo solo bisogno di pulire la nostra cache. FORNISCO FORTUNATO l'uso di questo tipo di strumento per le operazioni CRUD.

Ma, facendo ciò che hanno fatto i contributori di symfony, non è un compito facile. Ho implementato alcuni compiti di generazione del codice e fare qualcosa che sia veramente coerente e con un'implementazione ampia per coprire la maggior parte dei casi d'angolo non è facile.

È qualcosa che aumenterà davvero la tua produttività?

Credo che la metaprogrammazione sia molto importante nei livelli inferiori di lavoro (framework, caching, compilatori, ecc.) ma qualcosa che dobbiamo affrontare con estrema cautela se facciamo cose sul livello aziendale.

L'uso della generazione di codice è senza dubbio un grande incentivo alla produttività. Implementare i propri strumenti di generazione del codice, non tanto se non si sta costruendo un framework da soli.

Quali sono alcune buone risorse in materia, tra libri, blog, presentazioni, ecc?

La migliore risorsa per capire la programmazione è sempre un codice sorgente buono e ben commentato. Direi che esaminando RubyOnRails e Symfony i generatori di admin sono una buona idea.

    
risposta data 12.05.2012 - 13:13
fonte
3

Mentre molte risposte qui si riferiscono a ciò che è comunemente noto come meta-programmazione, c'era in realtà un campo associato all'IA noto come programmazione automatica che riguardava programmi comprensione o sintetizzare programmi [1].

Qualsiasi compilatore (o meta-programma, generatore di codice, traduttore, sistema macro, ...) funziona con le trasformazioni, generando un output da un input eseguendo il suo algoritmo di trasformazione fisso. Ma un compilatore o meta-programma tradizionale no, data una definizione, una descrizione o un esempio di ciò che ordina una lista (per esempio [5, 3, 9] = > [3,5,9]), crea un algoritmo di ordinamento . Tali problemi sono di interesse per questo campo di "programmazione automatica".

[1] - Report sui sistemi di comprensione del programma ftp://db.stanford.edu/pub/ CSTR / reports / cs /.../ CS-TR-74-444.pdfShare

    
risposta data 18.02.2013 - 04:35
fonte
2

La programmazione meta può essere molto difficile da mantenere. All'inizio sembra elegante, ma quando inizi a correre in casi d'angolo, gli errori vengono catturati in ritardo (sul codice che è stato generato) e l'intera cosa diventa un incubo da usare / debug.

Ho principalmente scritto il codice Python, e nella mia esperienza la meta-programmazione è sempre una cattiva scelta con questo linguaggio. Puoi sempre refactoring per farlo con noiose caratteristiche del linguaggio normale. Il risultato è meno funky, ma più facile da vivere.

    
risposta data 28.08.2011 - 12:50
fonte
2

L'OP chiede risorse.

Potresti trovare interessante il nostro DMS Software Reengineering Toolkit . È uno strumento di metaprogrammazione puro, progettato per consentire di creare strumenti personalizzati di analisi e trasformazione del programma.

[Per seguire un commento alla domanda dell'OP, quando viene utilizzato per creare uno strumento di trasformazione specifico, DMS è una linea di prodotti che scrive codice, che scrive codice:]

Il DMS raggiunge questo risultato essendo agnostico (ma non indipendente) delle lingue di programmazione target. DMS fornisce i servizi standard necessari per un'ampia gamma di compiti di metaprogrammazione, proprio come un sistema operativo offre una vasta gamma di servizi per attività di programmazione standard. Questi servizi includono un strong parsing, costruzione automatica di alberi di sintassi abstact, pattern-matching e riscrittura sugli alberi, librerie di tabelle di simboli che gestiscono facilmente le lingue con cattive regole di scoping come eredità multipla, flusso di controllo, flusso di dati, punti-a e chiamata analisi del grafico. Niente di tutto questo è significativo in assenza di specifiche lingue da elaborare, quindi DMS accetta definizioni di linguaggio che sono legate a questi pezzi generali di macchinari, producendo analisi specifiche per linguaggio, costruzione AST, pattern matching / riscrittura specifico per lingua di destinazione usando il target- sintassi del linguaggio, analizzatori specifici di target-langauge, ecc.

E come un sistema operativo, DMS è progettato per avere pochissime opinioni o vincoli su quali (meta) programmi si desidera scrivere, il che significa che può essere utilizzato per un'ampia varietà di scopi: estrapolazione di metriche, ricerca di codice morto, implementazione di aspetti tessitori, traduzione di lingue, generazione di codici da DSL, ricerca di grandi applicazioni. (DMS è già stato utilizzato per tutte queste attività).

Uno ha bisogno di solide definizioni linguistiche se non si vuole passare il tempo a codificare tutto nel manuale di riferimento di langauge (si pensi a cosa significa per Java e C ++). DMS risolve questo problema disponendo di una libreria di definizioni di langauge complete. L'analogico qui è un po 'come avere un database avaialbe per il tuo sistema operativo; non devi implementarne uno per continuare a scrivere la tua applicazione incentrata sul database.

    
risposta data 05.12.2011 - 03:13
fonte
2

Vedi il problema 4 di Philip Greenspun del corso MIT 6.916: Ingegneria software di servizi Web innovativi ( link ).

Il suo obiettivo dice: "Insegna agli studenti i pregi dei metadati. In particolare, apprendono come rappresentare formalmente i requisiti di un servizio Web e quindi creare un programma per generare i programmi per computer che implementano quel servizio."

Questo è uno dei problemi che imposta potenziali reclute ArsDigita ( link ) durante la prima bolla.

Il libro "SQL per Web Nerd" I riferimenti Philip nella pset sono stati spostati in ( link ).

    
risposta data 12.05.2012 - 11:44
fonte
2

Nel 2001 o intorno al 2001 ho iniziato a lavorare su un progetto che stava facendo ampio uso di oggetti aziendali e oggetti dati. Stavo costruendo il sito Web di front-end, ma ho appeso le mani sui miei pollici perché il livello aziendale e il livello di accesso ai dati non erano completamente sviluppati. Dopo un paio di settimane, ho iniziato a dare un'occhiata a quello che stavano facendo questi strati. Fondamentalmente, stavano esponendo i dati restituiti dalle stored procedure come raccolte di oggetti con proprietà corrispondenti ai campi nei dati, o stavano prendendo i parametri di input e li inviavano alle stored procedure per essere salvati nelle tabelle del database. C'era molta serializzazione / deserializzazione tra i due livelli, c'era Microsoft Transaction Server coinvolto, una libreria di tipi IDL / ODL ... ma tutto si adattava a un modello.

2 settimane dopo, ho elaborato un generatore di codice che avrebbe scaricato IDL / ODL e avrebbe anche scaricato gli oggetti business e dati. Per raggiungere il punto di debugging e testare questi oggetti, il tizio ha costruito gli oggetti business e di livello dati per 2 anni. In 2 settimane, con la generazione del codice, abbiamo avuto lo stesso risultato, ma poiché è stato generato tutto è stato abbastanza buono senza errori.

Quel generatore di codice (strumento CASE di livello inferiore) mi ha seguito attraverso molte iterazioni diverse, da circa 8 a 10 anni, perché il principio era così semplice: stai facendo qualcosa che deve essere fatto quando si parla di database , è praticamente una codifica ripetitiva, e una volta che hai capito bene non devi più preoccuparti di questo.

Quindi, sì: usa un generatore di codice, in particolare quando la codifica è ripetitiva e si adatta a un modello ben definito.

Ho conosciuto persone che usano le macro RegX per fare cose simili, o per usare le formule di Excel per fare cose simili (lo faccio anch'io).

    
risposta data 12.05.2012 - 21:58
fonte
2

Esempio di metaprogrammazione

Ho una libreria di autorizzazioni Ruby chiamata Authority . Consente agli sviluppatori di porre domande nella propria app con metodi come current_user.can_read?(@post) e @post.readable_by?(current_user) . Queste domande hanno una risposta da classi di authorizer centralizzate.

Questa è la parte cruciale: Authority non sa quali metodi definire fino a quando non vede la configurazione dell'utente . La configurazione utente potrebbe contenere:

config.abilities =  {
  ...
  :read      => 'readable',
  :microwave => 'microwavable',  # user-defined
  ...
}

In tal caso, è necessario un metodo come current_user.can_microwave?(@post) .

Metaprogramming lo rende possibile: dopo aver letto la configurazione, conosco quali metodi definire :

Authority.verbs.each do |verb|
  class_eval <<-RUBY, __FILE__, __LINE__ + 1 # allows for a nice bracktrace
    def can_#{verb}?(resource)
      resource.#{Authority.abilities[verb]}_by?(self)
    end
  RUBY
end
    
risposta data 12.05.2012 - 22:02
fonte