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.
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' –
Nie powinieneś zostawiać spacji między identyfikatorem metody a następującymi po nim parens. Ruby ostrzeże cię, kiedy to zrobisz. –