A che punto un file di configurazione diventa un linguaggio di programmazione?


90

È da un po 'che rifletto sui file di configurazione e sulla loro relazione con il codice e, a seconda del giorno e della direzione del vento, le mie opinioni sembrano cambiare. Tuttavia, continuo a tornare alla consapevolezza che ho avuto durante l'apprendimento del Lisp: c'è poca differenza tra dati e codice. Questo sembra doppiamente vero per i file di configurazione. Se guardato nella giusta luce uno script Perl è poco più di un file di configurazione per Perl. Ciò tende ad avere conseguenze piuttosto pesanti per attività come QA e divisioni del lavoro come chi dovrebbe essere responsabile della modifica dei file di configurazione.

Il passaggio dal file di configurazione al linguaggio completo è generalmente lento e sembra essere guidato dal desiderio di avere un sistema generico. La maggior parte dei progetti sembra iniziare in piccolo con alcuni elementi di configurazione come dove scrivere i log, dove cercare dati, nomi utente e password, ecc. Ma poi iniziano a crescere: le funzionalità iniziano a poter essere attivate o disattivate, i tempi e l'ordine delle operazioni iniziano a essere controllati e, inevitabilmente, qualcuno vuole iniziare ad aggiungervi logica (es. utilizzare 10 se la macchina è X e 15 se la macchina è Y). A un certo punto il file di configurazione diventa un linguaggio specifico del dominio, e uno scritto male.

Ora che ho divagato per preparare il palco, ecco le mie domande:

  1. Qual è il vero scopo di un file di configurazione?
  2. Dovrebbe essere fatto un tentativo per mantenere semplici i file di configurazione?
  3. Chi dovrebbe essere responsabile per le modifiche (sviluppatori, utenti, amministratori, ecc.)?
  4. Devono essere controllati alla fonte (vedere la domanda 3)?

Come ho detto prima, le mie risposte a queste domande cambiano costantemente, ma in questo momento sto pensando:

  1. per consentire a un non programmatore di modificare rapidamente grandi blocchi di comportamento
  2. sì, tutto ciò che non è a grana grossa dovrebbe essere in codice
  3. gli utenti dovrebbero essere responsabili dei file di configurazione ei programmatori dovrebbero essere responsabili di un livello di configurazione tra i file di configurazione e il codice che fornisce un controllo più fine dell'applicazione
  4. no, ma lo strato intermedio a grana più fine dovrebbe essere

23
Quando diventano Turing-complete, ovviamente!
aib

2
Le espressioni regolari non sono complete di Turing, ma sono ancora considerate un linguaggio informatico.
Chas. Owens

I "file" non sono realmente adeguati per alcune situazioni di configurazione. Da qui l'esistenza di sistemi come gconf.
Ali Afshar

1
Non c'è una vera differenza tra gconf e un file. Gconf è in realtà solo una serie di directory con file al loro interno con una rappresentazione in memoria. Anche se dovessi aprire un RDBMS, potrebbe essere rappresentato da un singolo file. Il problema è quanta complessità è sicura / buona in un file di configurazione.
Chas. Owens

Chas. È il modo in cui accedi al "file" che fa la differenza. E come gestisci le modifiche ai dati di configurazione quando sono connessi più client. Sì Gconf è rappresentato come file su un disco, ma si comporta in modo diverso. Se intendi "complessità dei dati di configurazione in un sistema di configurazione", certo.
Ali Afshar

Risposte:


40

Domande molto interessanti!

Tendo a limitare i miei file di configurazione a un formato "chiave = valore" molto semplice, perché sono pienamente d'accordo con te sul fatto che i file di configurazione possono diventare molto rapidamente programmi completi. Ad esempio, chiunque abbia mai provato a "configurare" OpenSER conosce la sensazione di cui parli: non è configurazione, è programmazione (dolorosa).

Quando hai bisogno che la tua applicazione sia molto "configurabile" in modi che non puoi immaginare oggi, allora ciò di cui hai veramente bisogno è un sistema di plugin . Devi sviluppare la tua applicazione in modo che qualcun altro possa codificare un nuovo plugin e collegarlo alla tua applicazione in futuro.

Quindi, per rispondere alle tue domande:

  1. Qual è il vero scopo di un file di configurazione?

    Direi, per consentire alle persone che installeranno la tua applicazione di essere in grado di modificare alcuni parametri relativi alla distribuzione, come il nome host, il numero di thread, i nomi dei plugin di cui hai bisogno ei parametri di distribuzione per quei plugin (controlla la configurazione di FreeRadius per un esempio di questo principio), ecc. Sicuramente non è il luogo per esprimere la logica aziendale.

  2. Dovrebbe essere fatto un tentativo per mantenere semplici i file di configurazione?

    Decisamente. Come hai suggerito, "programmare" in un file di configurazione è orribile. Credo che dovrebbe essere evitato.

  3. Chi dovrebbe essere responsabile per le modifiche (sviluppatori, utenti, amministratori, ecc.)?

    In generale, direi amministratori, che distribuiscono l'applicazione.

  4. Devono essere controllati alla fonte (vedere la domanda 3)?

    Io di solito non fonte di controllo i file di configurazione se stessi, ma io faccio fonte di controllo di un file di configurazione del modello, con tutti i parametri ed i loro valori di default, e commenti che descrivono ciò che fanno. Ad esempio, se un file di configurazione è denominato database.conf, di solito controllo il codice sorgente di un file denominato database.conf.template. Ora ovviamente sto parlando di quello che faccio come sviluppatore . In qualità di amministratore , potrei voler controllare il codice sorgente delle impostazioni effettive che ho scelto per ogni installazione. Ad esempio, gestiamo alcune centinaia di server in remoto e dobbiamo tenere traccia delle loro configurazioni: abbiamo scelto di farlo con il controllo del codice sorgente.


modificare: Anche se credo che quanto sopra sia vero per la maggior parte delle applicazioni, ci sono sempre delle eccezioni, ovviamente. La tua applicazione può consentire ai suoi utenti di configurare dinamicamente regole complesse, ad esempio. La maggior parte dei client di posta elettronica consente agli utenti di definire regole per la gestione delle proprie email (ad esempio, "tutte le email provenienti da 'giovanni doe' e che non sono presenti nel campo A: dovrebbero essere scartate"). Un altro esempio è un'applicazione che consente all'utente di definire una nuova offerta commerciale complessa. Potresti anche pensare ad applicazioni come Cognos che consentono ai propri utenti di creare report di database complessi. Il client di posta elettronica probabilmente offrirà all'utente una semplice interfaccia per definire le regole, e questo genererà un file di configurazione complesso (o forse anche un po 'di codice). D'altro canto, la configurazione definita dall'utente per le offerte commerciali può essere salvata in un database, in modo strutturato (né una semplice chiave = struttura valore né una porzione di codice). E alcune altre applicazioni potrebbero persino consentire all'utente di codificare in Python o VB, o in qualche altro linguaggio capace di automazione. In altre parole ... il tuo chilometraggio può variare.


10

Ok. Avrai alcuni utenti che vogliono una configurazione davvero semplice, dovresti darla a loro. Allo stesso tempo, avrai continue richieste di "Puoi aggiungere questo? Come faccio nel file di configurazione?", Non vedo perché non puoi supportare entrambi i gruppi.

Il progetto su cui sto attualmente lavorando utilizza Lua per il suo file di configurazione. Lua è un linguaggio di scripting e funziona abbastanza bene in questo scenario. È disponibile un esempio della nostra configurazione predefinita .

Noterai che sono principalmente istruzioni chiave = valore, dove valore può essere uno qualsiasi dei tipi incorporati di Lua. La cosa più complicata sono gli elenchi e non sono veramente complicati (è solo una questione di sintassi).

Ora sto solo aspettando che qualcuno chieda come impostare la porta del proprio server su un valore casuale ogni volta che lo avvia ...


1
+1 per l'utilizzo di un vero linguaggio di programmazione, molto più ordinato che lasciarne crescere uno da un file di configurazione
Benjamin Confino

+1: è l'approccio giusto. Lua ha una sintassi molto "simile alla configurazione" per coloro che sono nuovi. E consente potenti manipolazioni per coloro che non lo sono.
Andrew Y

8

Recentemente stavo lavorando a un progetto e mi sono reso conto che volevo avere condizionali all'interno del mio file di configurazione - che in precedenza era stato solo un piuttosto semplice del modulo:


key = val
key2 = val
name = `hostname`

Non volevo scrivere un mini-linguaggio, perché a meno che non lo facessi con molta attenzione non potevo permettere la flessibilità che sarebbe stata utile.

Invece ho deciso che avrei avuto due forme:

  1. Se il file inizia con "#!" ed era eseguibile, analizzerei il risultato dell'esecuzione.

  2. Altrimenti l'avrei letto così com'è

Ciò significa che ora posso consentire alle persone di scrivere "file di configurazione" che assomigliano a questo:

 #!/usr/bin/perl
if ( -x /bin/foo ) 
{
   print <<EOF;
foo=me
bar=you
EOF
}
else
{
   print <<EOF;
foo=bar
bar=foo
EOF
}

In questo modo ottengo la potenza di un file di configurazione dinamico se l'utente vuole usarlo e la semplicità di non dover scrivere il mio mini-linguaggio.


4

Ogni schema di file di configurazione (sufficientemente longevo) alla fine diventa un linguaggio di programmazione. A causa di tutte le implicazioni che descrivi, è saggio che il progettista del file di configurazione si renda conto che sta creando un linguaggio di programmazione e pianifichi di conseguenza, per evitare di caricare i futuri utenti con una cattiva eredità.


3

Ho una filosofia diversa sui file di configurazione. I dati su come eseguire un'applicazione sono ancora dati e pertanto appartengono a un archivio dati, non al codice (un file di configurazione IMO è codice). Se gli utenti finali devono essere in grado di modificare i dati, l'applicazione dovrebbe fornire un'interfaccia per farlo.

Uso solo i file di configurazione per puntare agli archivi dati.


3

Potresti rivolgerti alla teoria del calcolo per definire ciò che conta come linguaggio di programmazione. Se il formato del file di configurazione è Turing Complete, è ragionevolmente considerato un linguaggio di programmazione. In base a questa definizione, un formato di file per descrivere i livelli di Sokoban conta come linguaggio di programmazione (vedi qui ). Ci sono altri livelli di complessità al di sotto di Turing Complete che possono anche contare, come grammatiche regolari e automi pushdown .

Un altro modo per vederlo è che molti file di configurazione sono in grado solo di markup dei dati, mentre un linguaggio di programmazione appropriato deve essere in grado di implementare algoritmi . Ad esempio, JSON è un formato di file di configurazione, mentre ECMA Script è un linguaggio di programmazione.


2

Ecco i miei pensieri:

  1. Per consentire di modificare facilmente il comportamento di runtime di un'applicazione. Questo può essere da programmatori o non programmatori, a seconda delle esigenze. Questo può avvenire durante lo sviluppo, ma spesso vedo i file di configurazione come un modo per rendere un programma più flessibile in qualsiasi momento.

  2. Sì. Penso che i file di configurazione dovrebbero essere il più semplici possibile, dato il vincolo che potresti aver bisogno di varie opzioni per controllare diversi comportamenti del tuo runtime. Preferisco raggruppare le impostazioni di configurazione e semplificarle il più possibile.

  3. Dipende da cosa e perché viene apportata la modifica. Se gli utenti lo modificheranno, dovrebbe essere creato un front-end per nasconderli dai dettagli. Lo stesso vale spesso per i non sviluppatori in generale.

  4. Spesso controllo il codice sorgente della configurazione "predefinita", ma ho un modo per sovrascriverlo per sistema per il runtime effettivo.

Per quanto riguarda l'aggiunta di logica al file di configurazione, lo eviterei. Penso che sia meglio avere solo il file di configurazione che attiva la logica nella tua applicazione. Il comportamento nei file di configurazione porta a una mancanza di manutenibilità e comprensione, nella mia esperienza. Preferisco fortemente mantenere i file di configurazione il più semplici possibile.


2

Tendo a concordare con la premessa di questa domanda. Evito di mettermi nei guai prevedendo in anticipo che ciò accadrà, e quindi non eseguire mai il mio sistema di configurazione.

  • O uso la funzionalità di configurazione dei sistemi operativi (come plist, gconf o qualsiasi altra cosa sia appropriata),
  • O un semplice file flat, come può essere gestito da qualcosa come un parser INI disponibile in commercio.
  • Mordere il proiettile e collegare un parser di linguaggio leggero, di solito lua, a volte tcl nell'applicazione,
  • Oppure archiviare i dati in un database relazionale SQLite o simile.

E rassegnarmi a convivere con qualunque decisione ho preso, o se non posso, rifattorizzare per utilizzare una delle scelte di cui sopra che meglio si adatta all'applicazione.

Il punto è che non c'è davvero alcun motivo per utilizzare una soluzione di configurazione sviluppata in casa. Per prima cosa, è più difficile per i tuoi utenti dover imparare un nuovo formato di configurazione specifico dell'applicazione. Inoltre, puoi trarre vantaggio da tutte le numerose correzioni di bug e aggiornamenti gratuiti quando si utilizza una soluzione standard. Infine, Feature creep viene messo a tacere, perché, beh, in realtà non puoi semplicemente aggiungere un'altra funzionalità senza davvero fare una profonda revisione perché il sistema di configurazione non è davvero nelle tue mani in primo luogo.


1

Dipende da cosa sei d'accordo con gli altri sviluppatori del team. Stai usando i file di configurazione come file di configurazione o stai creando un modello guidato un'applicazione .

Sintomi del file di configurazione che diventa un linguaggio di programmazione:

  • le coppie nome = valore iniziano a dipendere l'una dall'altra
  • senti il ​​bisogno di avere il controllo del flusso (es. se (questo) di quello )
  • la documentazione per il file di configurazione diventa essenziale per fare ulteriore sviluppo (invece di usare solo l'applicazione)
  • prima che il valore da config venga letto, è necessario disporre di un contesto (cioè i valori dipendono da qualcosa di esterno al file di configurazione stesso)

1

I file di configurazione invariabilmente si fanno strada fino a diventare brutti e illogici "linguaggi di programmazione a pieno titolo". Ci vuole arte e abilità per progettare buoni linguaggi di programmazione, e i linguaggi di configurazione trasformati in linguaggio di programmazione tendono ad essere orrendi.

Un buon approccio consiste nell'usare un linguaggio ben progettato, diciamo python o ruby, e usarlo per creare un DSL per la tua configurazione. In questo modo il tuo linguaggio di configurazione può rimanere semplice in superficie ma in realtà essere il linguaggio di programmazione completo.


1

Credo che la tua domanda sia molto rilevante visto il passaggio a "interfacce fluenti". Molti sviluppatori hanno "visto la luce" rispetto alle applicazioni configurate in XML. L'utilizzo di XML può essere molto dettagliato e difficile da modificare correttamente (soprattutto se non viene fornito alcuno schema). Avere un'interfaccia fluente consente allo sviluppatore di configurare l'applicazione in un linguaggio specifico del dominio con l'assistenza di alcune coppie chiave-valore da un file di configurazione di testo semplice (o forse parametri della riga di comando). Rende anche molto facile impostare e configurare nuove istanze dell'applicazione per il test o altro.

Ecco le mie risposte alla tua domanda:

  • Qual è il vero scopo di un file di configurazione?

Un file di configurazione è un modo per consentire all'utente di personalizzare il comportamento del proprio programma in fase di esecuzione.

  • Dovrebbe essere fatto un tentativo per mantenere semplici i file di configurazione?

Idealmente, penserei che i file di configurazione dovrebbero almeno essere integrati da un'interfaccia fluente per configurare il programma (questo è utile sotto molti aspetti). Se hai bisogno di un file di configurazione, dovrebbe essere mantenuto molto semplice, nient'altro che coppie chiave-valore.

  • Chi dovrebbe essere responsabile per le modifiche (sviluppatori, utenti, amministratori, ecc.)?

Penso che la risposta a questa domanda dipenda dalla tua organizzazione. Dovrebbe essere responsabilità della persona che distribuisce il software assicurarsi che sia configurato correttamente.

  • Devono essere controllati alla fonte (vedere la domanda 3)?

Ruberò questa risposta a qualcun altro :) Mi piace l'idea di memorizzare una configurazione del modello nel controllo del codice sorgente e di modificarla per le esigenze di ogni utente locale. È probabile che il file di configurazione di uno sviluppatore sia l'incubo di un altro sviluppatore, quindi è meglio lasciare le cose che variano a seconda dell'utente fuori dal controllo del codice sorgente. Avere un modello è anche un bel modo per consentire alla persona che distribuisce l'applicazione (o ad altri sviluppatori) di vedere esattamente quali valori sono validi per il file di configurazione.


1

Ho visto programmi Python in cui il file di configurazione è codice. Se non hai bisogno di fare nulla di speciale (condizionali, ecc.) Non sembra molto diverso dagli altri stili di configurazione. ad esempio, potrei creare un file config.pycon cose come:

num_threads = 13
hostname = 'myhost'

e l'unico onere per l'utente, rispetto a (diciamo) file INI, è che devono mettere "" attorno alle stringhe. Senza dubbio potresti fare la stessa cosa in altre lingue interpretate. Ti dà la possibilità illimitata di complicare il tuo file di configurazione se necessario, a rischio di spaventare i tuoi utenti.


0

Sì, i file di configurazione dovrebbero essere semplici. Non dovrebbero contenere alcuna "logica": pensatele come un elenco di espressioni nelle istruzioni if, non come le istruzioni condizionali nella loro interezza.

Sono lì per consentire all'utente di decidere quale delle opzioni codificate all'interno dell'applicazione deve essere utilizzata, quindi non cercare di complicarle, finirà per essere controproducente: potresti finire per scrivere semplici file di configurazione per controllare come il file di configurazione originale dovrebbe essere configurato altrimenti!


0

Uno degli scopi del lavoro "Oslo" in Microsoft è quello di consentire (anche se non di richiedere) la risoluzione di questo problema.

  1. Un'applicazione verrebbe fornita con i modelli di tutti i nuovi componenti che include. Utilizzerebbe anche modelli esistenti. Ad esempio, potrebbe includere un servizio Web, quindi potrebbe riutilizzare il modello di sistema di un servizio Web.
  2. I modelli includeranno metadati che li descrivono, comprese informazioni sufficienti per consentire agli strumenti di accedervi, sia testualmente che graficamente.
  3. Parti dei modelli corrisponderanno alla "configurazione"

Ciò significa che l'equivalente dei file di configurazione odierni può essere abbastanza ricco da supportare la modifica sia testuale che grafica della loro configurazione. Lo strumento grafico verrà fornito con "Oslo" (nome in codice "Quadrant").


0

Sarò il contrarian e sostengo che è solo un linguaggio quando incorpora più di quanto possa essere rappresentato da XML; oppure quando XML è considerato un linguaggio.

In alternativa, la maggior parte dei file di configurazione può essere considerata come classi, ma con solo proprietà e nessun metodo. E senza metodi, non credo sia un linguaggio.

In definitiva, il "linguaggio" è un'astrazione morbida, ma sì, i bordi sono ambigui.


0

Il codice delle nostre applicazioni diventa meno importante ... C'è lo scripting, ci sono tutti i tipi di attributi che definiscono il comportamento di classi, metodi, argomenti e proprietà del metodo. Gli utenti possono definire trigger di database e vincoli di database. Possono esserci file di configurazione molto complicati. A volte l'utente può definire fogli di stile XSLT per manipolare input e output perché i nostri sistemi devono essere aperti (SOA). E ci sono cose come BizzTalk che richiedono anche una configurazione complessa. Gli utenti possono definire flussi di lavoro complessi.

Dobbiamo scrivere un codice migliore per gestire questo ambiente complesso, quindi il codice delle nostre applicazioni diventa più importante ...


0

Sono un grande fan dell'utilizzo di programmi Python come file di configurazione, specialmente per i demoni. Mi piace prendere la decisione di rendere il demone completamente vuoto di configurazione tranne che per la "porta di configurazione". Il programma python si connette quindi al daemon e procede alla creazione di oggetti nel daemon e li collega insieme per creare la configurazione desiderata. Una volta che tutto è impostato, il demone può essere lasciato in esecuzione da solo. I vantaggi, ovviamente, sono che ottieni un linguaggio di programmazione completo per scrivere i tuoi file di configurazione e poiché hai già un modo per parlare con il demone da un altro programma, puoi usarlo per il debug e ottenere statistiche. Il principale svantaggio è dover gestire i messaggi di un altro programma in arrivo in qualsiasi momento.


0

File di configurazione : "Qual è il mio scopo?"
Tu : "Configura il burro".
File di configurazione : "Ok ..."
File di configurazione : "Qual è il mio scopo?"
Tu : "Tu configuri il burro".
File di configurazione : "Oh mio dio".

  1. Non esiste un "vero scopo" di un file di configurazione. È tutto ciò che ha senso per la tua applicazione. In generale, le cose che differiscono (o potrebbero differire) tra le macchine e non cambiano durante l'esecuzione dell'applicazione dovrebbero probabilmente essere in un file di configurazione. Impostazioni predefinite, porte e indirizzi per altri servizi sono tutti ottimi candidati. Anche chiavi e segreti sono ottimi candidati, ma dovrebbero essere gestiti separatamente dalla normale configurazione per motivi di sicurezza. Non sono d'accordo sul fatto che lo scopo di un file di configurazione sia quello di consentire modifiche rapide da apportare. Lo scopo dovrebbe essere quello di consentire la flessibilità nella configurazione dell'applicazione. Se un file di configurazione un breve facile modo per consentire che la flessibilità, tanto meglio - ma si dovrebbe non essere intenzione vostri file di configurazione da cambiare frequentemente.

  2. Sì e no. Dovresti provare a rendere semplice il codice della tua applicazione? Sì. Dovresti cercare di rendere tutto ciò che scrivi semplice e pertinente. Non più complicato di quanto dovrebbe essere. Lo stesso vale per la tua configurazione. Tuttavia, questo è molto specifico dell'applicazione. Codificare ciò che dovrebbe essere nella configurazione perché renderebbe la configurazione "troppo complicata" è un cattivo design. In effetti, cercare di "mantenere le cose semplici" è il motivo per cui i file di configurazione finiscono per essere un enorme pasticcio. A volte la mossa più semplice è modulare. Questo è il motivo per cui i file di configurazione dovrebbero essere scritti in un ben noto linguaggio di programmazione generico - non in qualche terribile linguaggio di configurazione (leggi: tutti i "linguaggi di configurazione" fanno schifo ).

  3. Di nuovo, chi dovrebbe modificare i file di configurazione dipende completamente dall'applicazione. Ma sono d'accordo con miniquark, chiunque stia distribuendo l'applicazione dovrebbe essere responsabile della configurazione.

  4. Controlla tutto ciò che puoi. Il controllo del codice sorgente è ottimo. Puoi ripristinare le cose molto facilmente e hai una cronologia completa delle modifiche che hai apportato e un record di chi ha apportato tali modifiche. Quindi perche no?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.