Come possono essere create variabili in fase di runtime? [chiuso]

5

È possibile definire le variabili in modo dinamico?

Ieri sera stavo scrivendo del codice (C e VB2010) e mi sono imbattuto in un problema relativo alla definizione delle variabili nel mio programma. Le variabili necessarie dipendono dal numero di voci aggiunte dall'utente e dal numero di utenti. Anche usando l'allocazione dinamica della memoria abbiamo un limite di dimensioni, ma a volte mi chiedo di questo tipo di cose. Possiamo definire tante variabili quante ne abbiamo bisogno (al limite ovviamente) quando scriviamo il codice, ma non possiamo definirne di più in fase di runtime?

Ad esempio: dì che tutto il tuo programma è finito e quando l'utente dice 'x', questo non può essere creato come variabile; piuttosto abbiamo bisogno di una variabile per memorizzare quella x. Perché non possiamo rendere x una variabile in fase di runtime? Non possiamo costruire un ponte tra la compilazione-tempo e il runtime con alcune regole?

    
posta niko 23.08.2011 - 15:08
fonte

7 risposte

13

Le lingue digitate dinamicamente possono definire le variabili dinamicamente. Javascript ha oggetti basati su prototipi che possono essere definiti e utilizzati come segue:

var myObj =  {}; // Empty object

// Define var1 in myObj
myObj.var1 = "Hello World";

// Use var1    
console.log(myObj.var1);
// Prints: Hello World

// Redefine var1 in myObj
myObj.var1 = 1336;

// Use var1 again
console.log(myObj.var1 + 1);
// Prints: 1337

Nei linguaggi tipizzati staticamente, come Java, devi risolverlo in un modo diverso. Un modo semplice per emulare variabili dinamiche è utilizzare la mappa struttura dati (Map in Java, aka. Dizionario in . NET o Array associativi ) molto simile a come le variabili assegnate dinamicamente sotto il cappuccio in linguaggi come Javascript:

Map<String, Object> vars = new HashMap<String,Object>();

// Define a variable:
vars.put("var1") = "Hello World";

// Use a variable:
System.out.println(vars.get("var1"));
// Prints: Hello World

// Redefine variable (1336 int is actually boxed into an Integer object):
vars.put("var1") = 1336;

// Use the variable again, type casting is needed:
System.out.println(1 + ((Integer) vars.get("var1")));
// Prints: 1337

Quindi ci sono modi per emulare la gestione dinamica delle variabili di tipo in un linguaggio tipizzato staticamente come Java, ma sarà più dettagliato che in un javascript digitato in modo dinamico.

Modifica:

Solo per rispondere all'OP in modo più diretto:

say your whole program is done and when user says 'x', this cannot be created as variable; rather we require a variable to store that x. Why cant we make x a variable at runtime?

Come ho accennato nella mia risposta: Sì, puoi emulare questo comportamento. Ho creato una piccola classe Java per dimostrare l'esempio ed è disponibile come Gist . Sentiti libero di eseguire il codice di esempio e continuare a violare su di esso.

    
risposta data 23.08.2011 - 15:27
fonte
12

È sicuramente possibile in un linguaggio sufficientemente dinamico. Tuttavia, raramente è considerato una buona idea anche in quelle lingue. Ecco alcuni motivi:

  • Non è necessario. Esistono array associativi, che per definizione associano un nome a un valore, come fanno le variabili (vengono infatti utilizzati per implementare variabili e membri degli oggetti, almeno in parte, in un alcune delle lingue sopracitate). Le tabelle hash sono in realtà più potenti delle variabili in molti linguaggi (in particolare quelli statici): si ottiene un intervallo di operazioni che non hanno necessariamente senso per le variabili, ad esempio l'iterazione sui tasti.
  • Mette in discussione le preoccupazioni. L'input dell'utente è separato dai nomi utilizzati nella tua implementazione, l'input dell'utente non dovrebbe interrompere il sistema perché capita di interferire con uno dei nomi delle tue variabili. Se si desidera trattare gli input dell'utente come variabili, questi devono almeno essere nel loro ambito. E poi torni ad usare manualmente gli oggetti per raccogliere input da parte degli utenti - chiamali come array associativi o chiamali scope dinamicamente creati, è esattamente la stessa cosa. Tranne che gli array associativi sono concettualmente più semplici, più ampiamente supportati, possibili più potenti e più immediatamente riconosciuti.

Per rendere esplicito ciò che è stato sottinteso sopra: Usare un array associativo è come le variabili che creano dinamicamente! È semplicemente limitato al suo scopo, che è buono e che cosa vorresti comunque.

Si noti anche quanto sia ridicolmente difficile integrarlo con le viste del linguaggio statico sulle variabili. Il codice C ++ non ha nomi variabili in fase di esecuzione, stai suggerendo di eliminare tutte le ottimizzazioni associate e di introdurre un sistema ridicolmente complicato per la compilazione dinamica del codice, solo così puoi fare la stessa cosa di prima con un nome diverso?

    
risposta data 23.08.2011 - 15:39
fonte
9

costruire qualsiasi cosa in fase di esecuzione può essere fatto in due modi:

  1. Cose immesse dinamicamente dall'utente
  2. Cose che sono equivalenti al codice di scrittura

Il primo è qualcosa che quasi tutti gli sviluppatori fanno. Il numero di elementi per pagina di un elenco a pagine, la percentuale di imposte o il colore di sfondo di un modulo o qualsiasi cosa di questa essenza è davvero facile da diventare dinamico.

Tuttavia, quello che chiedi è come cercare di produrre codice in fase di esecuzione. Ad esempio, se abbiamo 2 variabili:

string firstName;
int age;

ora vuoi introdurre la terza variabile in fase di esecuzione:

string[] interestes;

L'unica cosa che mi viene in mente è attraverso la generazione del codice in fase di esecuzione, quindi la ricompilazione del tempo di esecuzione, la chiamata e l'esecuzione. Ad esempio, in .NET, lo spazio dei nomi di System.CodeDom è dedicato a questo problema.

    
risposta data 23.08.2011 - 15:19
fonte
7

Quello che stai cercando di fare qui si chiama meta-programmazione. Scrivere un codice che scrive il codice. Una cosa molto popolare con gli sviluppatori di ruby (rails). È anche possibile in ObjectiveC. Probabilmente anche altri linguaggi, perché non sono esperto in altri.

    
risposta data 23.08.2011 - 15:13
fonte
4

Puoi puoi farlo in c modificando dinamicamente il codice ma quasi certamente non vuoi fare altro che interessi educativi.

Hai menzionato l'allocazione dinamica della memoria (malloc e friends in c) e poi hai parlato di avere ancora dei limiti. Tieni presente che, tuttavia, quando crei le variabili, esistono ancora dei limiti. Se si creano variabili automatiche in fase di esecuzione, vengono create nello stack (limitato). Se stai creando globals, si siedono nello spazio var (limitato).

Penso che risolverei questo in c usando malloc. Sì, devi porre dei limiti, ma almeno puoi definire quali sono questi limiti e gestirli con garbo.

    
risposta data 23.08.2011 - 15:35
fonte
2

Sebbene l'argomento della creazione dinamica del codice, la sua compilazione e l'integrazione nell'applicazione attualmente in esecuzione sia interessante, non sono sicuro che sia ciò che stai cercando.

Il tuo problema che sta leggendo un numero indefinito di voci in un formato non noto in anticipo e fare qualcosa con questi non sembra molto complicato, o forse mi sbaglio ... il codice di esempio di Spoike sarebbe sufficiente. Se vuoi più di "mappe", allora sì, potresti aver bisogno di "meta fagioli", come ad esempio bean dinamici (questo è un esempio Java). La libreria BeanUtils di Apache potrebbe essere esattamente ciò che stai cercando.

Modifica: in .NET è possibile utilizzare Spring.NET Il framework, in quanto supporta linguaggi dinamici come Groovy per esempio.

    
risposta data 23.08.2011 - 15:44
fonte
0

Sembra che tu stia pensando a un interprete . Quindi usa le tecniche classiche: scrivi un parser che crea un abstract syntax tree quindi valuta l'AST in alcuni ambienti (alcune variabili di associazione della mappa ai valori).

Le variabili nella tua lingua interpretata non sono correlate alle variabili del tuo codice interprete.

Leggi anche su lingue omoiconiche

Ancora meglio, non scrivere il tuo interprete, ma incorporarne uno esistente come GNU guile o Lua .

È possibile generare codice C in fase di esecuzione, quindi compilarlo e caricarlo dinamicamente (ad esempio con dlopen su POSIX) come plug-in, vedere questo & che

    
risposta data 13.08.2015 - 11:45
fonte

Leggi altre domande sui tag