2010-06-09 27 views
19

Non capisco class_eval.Come si usa class_eval?

class Module 
    def attr_ (*syms) 
    syms.each do |sym| 
     class_eval %{def #{sym}= (val) 
     @#{sym} = val 
     end} 
    end 
    end 
end 

Che cosa significa "%"?

Cosa fa class_eval?

E da dove viene il numero (val)?

+0

Ho copiato il pastebin direttamente (e corretto la scrittura). Presumo che l'ultimo '}' sia mal riposto; dovrebbe essere dopo 'val', non dopo' end' –

+0

Non dovresti lasciare uno spazio tra un identificatore di metodo e i parenti che seguono. Ruby ti avviserà quando lo farai. –

risposta

23

La risposta breve è: probabilmente si desidera evitare utilizzando class_eval come questo.

Ecco una spiegazione del codice:

Il %{hello} è solo un altro modo di scrivere una stringa letterale in Ruby, senza doversi preoccupare di fuggire virgolette doppie o singole all'interno della stringa:

%{hello "world"} == "hello \"world\"" # => true 

Lo val nel codice è un argomento del metodo in fase di definizione.

Il class_eval viene utilizzato per definire alcuni metodi calcolando il testo che si scriverà per eseguire la definizione e quindi valutarla. Non è necessario qui, a proposito. Un codice equivalente sarebbe:

class Module 
    def attr_ (*syms) 
    syms.each do |sym| 
     define_method "#{sym}=" do |val| 
     instance_variable_set "@#{sym}", val 
     end 
    end 
    end 
end 

Questo è solo equivalente al builtin attr_writer.

Aggiornamento: Non ci può effettivamente essere una differenza significativa tra i due ...

La versione class_eval è vulnerabile se non ci si può fidare l'argomento syms. Per esempio:

class Foo 
    attr_ "x; end; puts 'I can execute anything here!'; val=42; begin; val" 
end 

La versione class_eval stamperà "Posso eseguire nulla qui" due volte, dimostrando che può eseguire qualsiasi cosa. La versione define_method non stampa nulla.

Questo type of code è stato fondamentale per creare major vulnerability per tutte le app Rails installate.

+0

cosa significa la parola valutare? non capisco quella parola –

+3

In questo contesto, eseguire alcune istruzioni. Se dovessi "valutare" l'espressione 6 + 5, è 11. – ALW