La respuesta corta es: probablemente desee evite usando class_eval
de esta manera.
He aquí una explicación de su código:
El %{hello}
es sólo otra manera de escribir una cadena literal en Ruby, sin tener que preocuparse de escapar comillas simples o dobles dentro de la cadena:
%{hello "world"} == "hello \"world\"" # => true
El val
en su código es un argumento del método que se está definiendo.
El class_eval
se utiliza para definir algunos métodos calculando el texto que se escribiría para hacer la definición y luego evaluarla. No es necesario aquí, por cierto. Un código equivalente sería:
class Module
def attr_ (*syms)
syms.each do |sym|
define_method "#{sym}=" do |val|
instance_variable_set "@#{sym}", val
end
end
end
end
Esto es sólo equivalente a la orden interna attr_writer
.
actualización: Hay en realidad puede haber una diferencia significativa entre los dos ...
La versión class_eval
es vulnerable si no se puede confiar en el argumento syms
. Por ejemplo:
class Foo
attr_ "x; end; puts 'I can execute anything here!'; val=42; begin; val"
end
La versión class_eval
imprimirá "Puedo ejecutar nada aquí" dos veces, lo que demuestra que se puede ejecutar nada. La versión define_method
no imprimirá nada.
Este type of code fue esencial para crear major vulnerability para todas las aplicaciones de Rails instaladas.
He copiado tu pastebin directamente (y he reparado la escritura). Supongo que el último '}' está fuera de lugar; debe ser después de 'val', no después de' finalizar' –
No debe dejar un espacio entre un identificador de método y los parens que siguen. Ruby te avisará cuando lo hagas. –