2009-12-01 13 views
23

Mi sembra che lo eval() sia trattato con lo stesso sdegno di Goto. E per eval, intendo una funzione per l'esecuzione di una stringa come codice, come visto in PHP, Python, JavaScript, ecc. C'è mai una situazione in cui l'uso di eval() è giustificato (eccetto perl)? E se no, perché così tante lingue lo implementano?C'è mai una buona ragione per usare eval()?

+12

Questa domanda non può essere ** indipendente dalla lingua ** a causa del ruolo speciale del blocco 'eval' in Perl come principale meccanismo di gestione delle eccezioni. Pertanto, ti presento che non ci può essere una risposta corretta a questa domanda: C'è una buona ragione per usare 'eval' se stai programmando in Perl, e probabilmente non è una buona ragione se stai programmando in JavaScript. Specificare le lingue a cui si applica questa domanda o renderla CW. –

+1

Vero, non sapevo come eval() funzionasse in perl. – GSto

+1

Stai includendo la funzione 'eval' in Lisp? È essenziale nel normale funzionamento (il ciclo read-eval-print), ma nella mia esperienza non è quasi mai usato al di fuori di questo. Ogni volta che ero tentato, sembrava che le macro Common Lisp fossero un'idea migliore. –

risposta

25

Sì - quando non esiste un altro modo per eseguire l'attività fornita con un livello ragionevole di chiarezza e entro un numero ragionevole di righe di codice.

Questo elimina il 99% dei casi in cui viene utilizzato lo eval, in tutte le lingue e in tutti i contesti.

3

Per gli attacchi rapidi, nessun problema perché è un utile quick-out.

Nel codice di produzione, considerarlo l'ultima risorsa, e anche in questo caso, provare qualcos'altro, perché eval è difficile da controllare e quindi pericoloso. Per qualsiasi cosa non banale, implementa una lingua in più.

1

Scrivere un esempio di libro freddo su quanto sia facile implementare una "calcolatrice" nella lingua X? =)

2

Pensiero parziale: eval è utile per implementare un compilatore di espressioni di un uomo povero, o cose del genere. È anche un sostituto noioso e arrugginito per i macro igienici.

3

L'ho usato una volta durante il pentesting di un sito: abbiamo scritto un piccolo script php che decrittografa ed esegue i payload firmati crittograficamente da origini dati HTTP non registrate al volo. Questo è l'uso migliore che ho visto di eval() finora.

(in altre parole: no, non ho mai visto un buon uso per eval)

2

Forse io uso sh e perl troppo, ma non ho mai visto nessuno trattare eval con il disprezzo che goto ottiene .

Quindi la mia risposta è: 'eval è adatto quando si scrive perl 5 e sh'. Il blocco eval è il meccanismo try/catch primario in Perl e il relativo codice di sicurezza difficile da scrivere senza di esso.

+0

hai ragione, forse non è esattamente come lingua-agnostica come pensavo. La mia esperienza è con PHP e Python, e il consenso generale sembra essere che se si desidera utilizzare eval, non farlo. Corollario – GSto

+1

: non taggare nulla come "linguaggio indipendente" a meno che non ti trovi a tuo agio con almeno una dozzina di lingue – Javier

9

eval è spesso la soluzione più conveniente in situazioni in cui si genera dinamicamente codice. Anche nelle lingue che non supportano ufficialmente Eval, come Java, supportano la riflessione e la modifica delle classi in fase di runtime che sono simili. (Vedi libri come Stu Halloway's Component Development for the Java Platform)

+0

+1, solo vero esempio che ho visto finora. –

4

Un uso ragionevole è se si dispone di un linguaggio interpretato che è stato costruito su un'altra lingua, ma si desidera comunque fornire una sorta di "tratteggio di escape" per consentire alle persone per tornare alle funzioni fornite dalla lingua sottostante Un esempio è l'implementazione di Prolog in Lisp e la definizione di un predicato che consente l'uso diretto delle funzioni Lisp tramite EVAL.

0

Per eseguire il debug/testare un'idea prima di implementarla nel modo corretto.

Ad esempio, stai facendo una calcolatrice giocattolo e prima vuoi lavorare sul gui, quindi usa semplicemente eval per fare il lavoro "back-end" in background. Successivamente, si ritorna al back-end, si gratta il eval e si scrive un parser di espressioni corretto.

0

Durante la creazione/test dei segmenti di codice eval è PERFETTO!

Basta creare una semplice pagina Web di scaffold con textareas e un pulsante eval. Inserisci il codice in un'area testo quindi premi il pulsante eval. E 'più veloce di passare avanti e indietro tra il vostro editor di testo e il browser

eval

edit code 
press eval button 

metodo di commutazione

edit code 
press save   extra step 
switch to browser extra step 
press reload 

Nel fare un sacco di test e messa a punto sul codice dei passaggi aggiuntivi minori può davvero addizionare. Inoltre potresti dimenticarti di risparmiare confusione durante i test.

+0

Oppure premi F12 e usa la console? – ShrekOverflow

+0

Utilizzare la console per modificare molte righe di codice? Non sembra pratico. – user3015682

0

Eval è utilizzato quando è necessario "generare" ed eseguire il codice. E per generare intendo includere da una fonte esterna (un file, un sito Web, un 'agente') e creare al volo all'interno del programma.

E il motivo per cui si desidera generare codice, oltre agli ovvi esempi di moduli esterni e siti di valutazione, è in genere per fare riferimento dinamicamente ai nomi di oggetti e proprietà nel codice.

Il primo esempio, btw, si verifica già quando una pagina HTML viene caricata e ha un tag script o negli attributi del gestore di eventi dei tag HTML - quindi fin dall'inizio uno sviluppatore web si sta avvantaggiando di EVAL, anche se è il browser che effettua la chiamata.

Ciò che indirettamente mi porta a questa seconda ragione - accedere ai nomi degli oggetti .. In alcune lingue come java, la capacità di introspezione riduce o elimina la necessità di utilizzare la valutazione di java. Risulta che poiché gli oggetti in Javascript sono completamente dinamici, un accesso di proprietà in Javascript è paragonabile all'introspezione in altre lingue, dove è possibile accedere e fare riferimento a nomi creati al volo. Inoltre, Javascript ha le funzioni 'chiama' e 'applica' per chiamare dinamicamente le funzioni con i loro parametri.

Infine, in relazione all'esecuzione del codice, è possibile utilizzare eval per aumentare le prestazioni: anziché un accesso condizionale o di proprietà multilivello che determina quale codice eseguire o quale oggetto utilizzare, si potrebbe creare uno snippet di codice minimo che potrebbe devono essere eseguiti centinaia di migliaia di volte, rivedendoli in una funzione e quindi richiamare semplicemente quella funzione. Ciò potrebbe funzionare con multimethod, ad esempio, una volta determinati gli argomenti specifici in uso. Certo, però, questo è un po 'diverso dal motivo dato che le funzioni di javascript funzionano come oggetti di prima classe.

Problemi correlati