Mentre OP ha già accettato una risposta utilizzando instance_eval(string)
, io suggerisco vivamente OP per evitare forme di stringa di eval
se non assolutamente necessario. Eval invoca il compilatore di rubini: è costoso da calcolare e pericoloso da utilizzare in quanto apre un vettore per gli attacchi di iniezione di codice.
quanto affermato non c'è alcuna necessità di inviare a tutti:
obj.foo.bar
Se, infatti, i nomi di foo e bar sono provenienti da qualche calcolo non statico, quindi
obj.send(foo_method).send(bar_method)
è semplice e tutto ce n'è bisogno per questo
Se i metodi provengono sotto forma di una stringa tratteggiata, si può usare dividere e iniettare a catena metodi:
'foo.bar'.split('.').inject(obj, :send)
chiarendo in risposta alle osservazioni: String eval è uno dei più rischioso uno cose può fare da una prospettiva di sicurezza. Se c'è un modo in cui la stringa viene costruita dall'input fornito dall'utente senza un'ispezione e una convalida incredibilmente diligenti di quell'input, dovresti semplicemente considerare il tuo sistema di proprietà.
send (metodo) in cui il metodo è ottenuto dall'input dell'utente presenta anche dei rischi, ma esiste un vettore di attacco più limitato. L'input dell'utente può causare l'esecuzione di qualsiasi metodo 0-argument dispacciabile tramite il ricevitore. La buona pratica qui sarebbe di whitelist sempre i metodi prima della spedizione:
VALID_USER_METHODS = %w{foo bar baz}
def safe_send(method)
raise ArgumentError, "#{method} not allowed" unless VALID_USER_METHODS.include?(method.to_s)
send(method)
end
'obj.send ('foo'). Send ('bar')' –
@SergioTulentsev - Scusa dovrei aver chiarito - C'è un modo per fallo in un solo passaggio. Quello che stai descrivendo richiede l'analisi della stringa "foo.bar" per rendersi conto che è necessario chiamare send() in modo ricorsivo. Mi stavo chiedendo se esistesse un meccanismo esistente che lo faccia automaticamente o più chiaramente. – Lynn
@Lynn: non sono a conoscenza di tale meccanismo integrato. –