2014-07-10 15 views
5

ho bisogno di un metodo che attraverso una stringa di input per fare un calcolo, come questostringa di convertire in funzione nel ruby-on-rails

function = "(a/b)*100" 
a = 25 
b = 50 
function.something 
>> 50 

hanno qualche metodo per esso?

+1

Se sei troppo sicuro usa 'Kernel # eval' ... Come' eval (function) '. –

+3

Non so cosa vuoi fare con esso ma per favore ** non si fida dell'input dell'utente **, cioè non usare qualcosa proveniente dagli utenti finali nella tua "stringa da valutare". – MrYoshiji

+0

Il mio onesto suggerimento è .. Per favore cambiate la vostra interfaccia, in modo che non sia necessario usare alcun '# eval'. Pensalo in un altro modo. Non serve usare alcuna * eval family * per fare * matematica *. –

risposta

7

È possibile utilizzare instance_eval:

function = "(a/b)*100" 
a = 25.0 
b = 50 

instance_eval function 
# => 50.0 

Attenzione però che utilizzando eval è intrinsecamente insicuro, soprattutto se si utilizza l'ingresso esterno, in quanto può contenere codice dannoso iniettato.

noti inoltre che a è impostato 25.0 anziché 25, poiché se è un intero a/b comporterebbe 0 (numero intero).

+0

+1 per soluzione semplice e chiara –

+5

Attenzione, questo può eseguire qualsiasi cosa nella vostra applicazione, es: User.destroy_all. –

+0

@BrunoMuceliniMergen, sì, ho menzionato questo nella mia risposta –

2

È possibile dare un'occhiata alla gemma dentaku, che è parser e analizzatore di formule matematiche e logiche.

require 'dentaku' 

a = 25.0 
b = 50 
function = "(#{a}/#{b})*100" 

calculator = Dentaku::Calculator.new 
calculator.evaluate(function) # => 50.0 

Non utilizzare eval.

+1

"Non utilizzare nessuna valutazione". C'è un tempo e un posto per 'eval'. 'eval' va bene quando * sai * cosa viene valutato. Se la stringa è creata dallo script e si basa su dati sterilizzati, allora è sicura. Non è sicuro quando i dati sono sconosciuti/non disinfettati. –

+0

@theTinMan Hai ragione. Ma proverò ancora la buona abitudine di non usare 'eval', e cercherò un * parser * matematico, come quello che ho mostrato qui. Non supporto, 'eval' usando, dove c'è un modo. '# instance_eval' o' # instance_exec' ha altri scopi, ma non lo sono per i calcoli matematici. In ogni caso è questione di gusti, di evitare il rischio. –

Problemi correlati