ruby-on-rails - programas - ruby modulos
¿Cómo convierto una cadena a un método de clase? (4)
Esta es la forma de convertir una cadena en una clase en Rails / Ruby:
p = "Post"
Kernel.const_get(p)
eval(p)
p.constantize
Pero, ¿qué sucede si estoy recuperando un método de una matriz / objeto de registro activo como:
Post.description
pero podría ser
Post.anything
donde algo es una cadena como anything = "description"
.
Esto es útil ya que quiero refactorizar una clase muy grande y reducir las líneas de código y la repetición. ¿Cómo puedo hacer que funcione?
Como esto está relacionado con una pregunta de Ruby on Rails, elaboraré un poco.
En Rails 3, asumiendo que title
es el nombre de un campo en un objeto ActiveRecord, entonces lo siguiente también es válido:
@post = Post.new
method = "title"
@post.send(method) # => @post.title
@post.send("#{method}=","New Name") # => @post.title = "New Name"
Prueba esto:
class Test
def method_missing(id, *args)
puts "#{id} - get your method name"
puts "#{args} - get values"
end
end
a = Test.new
a.name(''123'')
Entonces, la sintaxis general sería a.<anything>(<any argument>)
.
Si bien eval puede ser una herramienta útil para este tipo de cosas, y las personas de otros orígenes pueden necesitar usarlo tan a menudo como lo haría con un abrelatas, en realidad es peligroso usarlo de manera tan casual. Eval implica que cualquier cosa puede suceder si no tienes cuidado.
Un método más seguro es este:
on_class = "Post"
on_class.constantize.send("method_name")
on_class.constantize.send("method_name", arg1)
Object # send llamará al método que desee. Puede enviar un Símbolo o una Cadena y, siempre que el método no sea privado o esté protegido, debería funcionar.
Post.send(anything)