2010-06-09 13 views
19

Nie rozumiem class_eval.Jak używać class_eval?

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

Co oznacza %?

Co robi class_eval?

A skąd pochodzi (val)?

+0

Skopiowałem twój pastebin bezpośrednio (i poprawiłem pisanie). Przypuszczam, że ostatnie '}' jest źle umieszczone; powinno to być po 'val', a nie po' końcu' –

+0

Nie powinieneś zostawiać spacji między identyfikatorem metody a następującymi po nim parens. Ruby ostrzeże cię, kiedy to zrobisz. –

Odpowiedz

23

Krótka odpowiedź brzmi: prawdopodobnie chcesz uniknąć przy użyciu class_eval w ten sposób.

Oto wyjaśnienie kodu:

%{hello} to tylko kolejny sposób pisać ciąg dosłowne w Ruby, bez konieczności martwienia się o ucieczce podwójne lub pojedyncze cudzysłowy w ciąg:

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

Kod val w kodzie jest argumentem definiowanej metody.

Metoda class_eval służy do definiowania niektórych metod poprzez obliczanie tekstu, który można napisać w celu wykonania definicji, a następnie jej oceny. Nie jest to konieczne tutaj, BTW. Kod równoważny to:

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

Jest to odpowiednik wbudowanego attr_writer.

Aktualizacja: Nie może być rzeczywiście znacząca różnica między tymi dwoma ...

Wersja class_eval jest zagrożony, jeśli nie można zaufać argument syms. Na przykład:

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

Wersja class_eval będzie drukować „Mogę wykonać coś tutaj” dwa razy, udowadniając może wykonać wszystko. Wersja define_method niczego nie wydrukuje.

Ten numer type of code miał decydujące znaczenie dla utworzenia major vulnerability dla wszystkich zainstalowanych aplikacji Railsowych.

+0

co oznacza słowo ocena? Nie rozumiem tego słowa. –

+3

W tym kontekście wykonaj niektóre instrukcje. Jeśli miałeś "ocenić" wyrażenie 6 + 5, to jest 11. – ALW