Non ho mai avuto problemi con le variabili globali in Bash o JavaScript, molto probabilmente perché ho scritto solo piccoli script per uso personale su ambienti minimalisti.
Perché molti programmatori evitano di usare variabili globali e ci sono esempi di violazioni della sicurezza causate dall'uso di variabili globali?
In piccoli progetti le variabili globali vanno benissimo. La maggior parte dei loro problemi non si presentano. E la personalizzazione dell'ambiente Bash di cui sopra è davvero minuscola.
Le variabili globali iniziano a causare problemi mentre il tuo programma scala; il che può accadere in molti modi, ma la parte centrale del problema è la quantità di stato richiesta dalla comprensione di ogni parte di codice.
Immagina una base di codice di 10 milioni di righe . In esso ci sono 1 milione di variabili. Sono tutte globali.
In un dato pezzo di codice di 100 righe, potresti usare 20 variabili.
Ogni volta che chiami una funzione, non hai idea di quale di queste 20 variabili verrà modificata; quando la tua funzione viene avviata, non hai idea da dove provenga la variabile state.
Quindi, per capire cosa significano le tue 100 righe di codice, devi capire e tenere a mente tutti i 10 milioni di righe di codice, oppure una sorta di convenzione sulla provenienza dei dati, quali dati possono e non possono essere modificati quando chiami una funzione di supporto, ecc.
Al contrario, se il tuo codice è quasi interamente alimentato da argomenti di funzione, variabili locali e tipi restituiti, devi solo capire la tua funzione per capire cosa fa. Inoltre, se quella funzione chiama un'altra funzione, sai quali informazioni le stai passando e quali informazioni restituisce.
Potresti non sapere cosa fa con queste informazioni, ma sai cosa non fa .
Ad esempio, non può modificare intero x
e ne sei certo, perché non hai passato x
alla funzione, né le hai assegnato dal suo valore di ritorno!
Rendere il codice più facile da ragionare su localmente è un obiettivo molto importante. Vuoi essere in grado di leggere una funzione, sapere cosa sta facendo e identificare i bug.
Scrivere codice è molto più semplice e molto meno importante che creare codice chiaro e di facile ragionamento.
Quasi tutto il codice in un progetto ampio e persistente viene letto centinaia di volte più spesso di quanto non venga modificato e viene scritto e progettato una sola volta.
Da questa regola, rendiamo più facile ragionare a livello locale. raggiungere la regola di "evitare lo stato globale".
Variabile globale contro Super-oggetto
Le variabili globali che vengono lette / scritte sono un esempio di stato globale. Ma lo stesso può essere un superoggetto a cui ogni cosa nel progetto ha un puntatore a cui passare come primo argomento.
Un superoggetto ha ancora dei vantaggi rispetto alle variabili globali; le variabili globali spesso hanno meccanismi confusi su come vengono inizializzate e ripulite (ti sto guardando, C / C ++), e se hai un superoggetto con tutto il tuo stato "globale" puoi istanziare due versioni del tuo superoggetto ed eseguirli contemporaneamente nello stesso processo (questo tenderà a non funzionare, ma di solito è a causa di uno stato globale implicito che il sistema operativo ti impone).
Ogni variabile globale che leggi, invece di un parametro, significa che qualsiasi bit di codice , ovunque potrebbe modificarne il comportamento. Ogni variabile globale su cui scrivi significa che stai modificando il comportamento di un codice arbitrariamente lontano.
E non sono solo gli umani a trovare gli stati globali un dolore; se il tuo stato è locale, scrivere test imbriglia che "fingere" uno stato o ambiente globale diventa molto più semplice. Se c'è (diciamo) un oggetto "mouse" globale, scrivere un test unitario che crea un mouse falso che finge di fare un certo movimento diventa più difficile, potrebbe anche essere più difficile scrivere una macro che riproduce un movimento del mouse registrato in un codice, soprattutto se intendi farlo mentre l'interfaccia utente rimane sensibile all'effettivo essere umano che utilizza un mouse.
Sicurezza
La sicurezza è una funzione della comprensione di ciò che fa il tuo codice. Sicurezza, all'interno di un programma, significa "il tuo codice fa solo ciò che dovrebbe essere autorizzato a fare"; con le variabili globali, hai una capacità più debole di capire cosa fa il codice, quindi meno capacità di controllare ciò che fa.