¿Alguien puede decirme qué?
send("#{Model.find...}")
es y hace?
¿Alguien puede decirme qué?
send("#{Model.find...}")
es y hace?
Respuestas:
send
envía un mensaje a una instancia de objeto y sus ancestros en la jerarquía de clases hasta que algún método reacciona (porque su nombre coincide con el primer argumento).
Prácticamente hablando, esas líneas son equivalentes:
1.send '+', 2
1.+(2)
1 + 2
Tenga en cuenta que send
omite las comprobaciones de visibilidad, por lo que también puede llamar a métodos privados (útil para pruebas unitarias).
Si realmente no hay una variable antes del envío, eso significa que se usa el Objeto global:
send :to_s # "main"
send :class # Object
send es un método ruby (sin rieles) que permite invocar otro método por su nombre.
De la documentación
class Klass
def hello(*args)
"Hello " + args.join(' ')
end
end
k = Klass.new
k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
Una de las características más útiles que creo con el método .send es que puede llamar dinámicamente al método. Esto puede ahorrarle mucho escribir. Uno de los usos más populares del método .send es asignar atributos de forma dinámica. Por ejemplo:
class Car
attr_accessor :make, :model, :year
end
Para asignar atributos con regularidad, se necesitaría
c = Car.new
c.make="Honda"
c.model="CRV"
c.year="2014"
O usando el método .send:
c.send("make=", "Honda")
c.send("model=", "CRV")
c.send("year=","2014")
Pero todo se puede reemplazar con lo siguiente:
Suponiendo que su aplicación Rails necesita asignar atributos a su clase de automóvil desde la entrada del usuario, puede hacerlo
c = Car.new()
params.each do |key, value|
c.send("#{key}=", value)
end
Otro ejemplo, similar al https://stackoverflow.com/a/26193804/1897857 de Antonio Jha
es si necesita leer atributos en un objeto.
Por ejemplo, si tiene una matriz de cadenas, si intenta recorrerlas y llamarlas en su objeto, no funcionará.
atts = ['name', 'description']
@project = Project.first
atts.each do |a|
puts @project.a
end
# => NoMethodError: undefined method `a'
Sin embargo, puede send
las cadenas al objeto:
atts = ['name', 'description']
@project = Project.first
atts.each do |a|
puts @project.send(a)
end
# => Vandalay Project
# => A very important project
define_method
: apidock.com/ruby/Module/define_method .
send
es otra forma de llamar a un método.
Esto se ilustra mejor con un ejemplo:
o = Object.new
o.send(:to_s) # => "#<Object:0x00005614d7a24fa3>"
# is equivalent to:
o.to_s # => "#<Object:0x00005614d7a24fa3>"
Envía vidas en la clase Objeto .
El beneficio de este enfoque es que puede pasar el método que desea llamar como parámetro. He aquí un ejemplo sencillo:
def dynamically_call_a_method(name)
o = Object.new
o.send name
end
dynamically_call_a_method(:to_s) # => "#<Object:0x00005614d7a24fa3>"
Puede pasar el método al que desea que se le llame. En este caso pasamos :to_s
. Esto puede ser muy útil cuando hacemos metaprogramación de ruby, porque nos permite llamar a diferentes métodos de acuerdo con nuestros diferentes requisitos.
Otro caso de uso para las vistas:
<%= link_to
send("first_part_of_path_#{some_dynamic_parameters}_end_path",
attr1, attr2), ....
%>
Permitir. que escriba una vista escalable que trabaje con todo tipo de objetos con:
render 'your_view_path', object: "my_object"