¿Es esta toda la línea de código? Quiero decir, ¿no hay nada antes de 'enviar'?
jirafa
Respuestas:
107
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'+',21.+(2)1+2
Tenga en cuenta que sendomite 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:
Oh, ya veo, entonces uno podría usar enviar si uno quisiera almacenar algo como 1 mes en la base de datos en lugar de decir estáticamente el número de días.
Christian Bankester
3
Es cierto que podría usarlo para llamar a métodos con nombres calculados, no estáticos. (Sin embargo, no debe permitir la entrada del usuario sin restricciones para evitar llamar a métodos privados ... Sin embargo, podría darles un prefijo único: enviar 'user_method _' + nombre de método, * args)
giraff
2
Un buen caso de uso podría ser si desea probar un método de clase protegida, podría llamarlo fuera de una clase, en un archivo de prueba ...
GN.
106
send es un método ruby (sin rieles) que permite invocar otro método por su nombre.
Gran respuesta, más clara que la verbosa respuesta aceptada.
codificación aaron
63
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:
classCar
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"
El uso de .send de esta manera agrega una complejidad innecesaria y facilita la introducción inadvertida de un error en el código. Por ejemplo, en su código anterior, si agrega una nueva entrada a su hash de parámetros (como 'cilindros'), el código fallará con un error de método indefinido.
Kevin Schwerdtfeger
1
¿responder a? podría utilizarse para evitar tales errores, si se desea.
Richard_G
1
¡Esta fue una gran explicación! ¡Gracias Jha!
Sharath
1
@Kevin tienes razón, pero a veces puede ser necesario. Más flexibilidad se correlaciona con más riesgo, que puede mitigarse.
¡Gracias! Esa es exactamente la respuesta que busco. ¿Se pregunta si esto se usa comúnmente? Me encontré con algo similar en el código heredado, no estoy seguro de poder seguir con él. @ Mike Vallano
B Liu
1
@ b-liu Lo he visto usado por desarrolladores experimentados en código nuevo. También puede ser útil cuando se usa define_method: apidock.com/ruby/Module/define_method .
Mike Vallano
¡Increíble! ¡Montones de gracias! @MikeVallano
B Liu
4
¿Qué hace enviar?
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>"
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.
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:
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:
fuente
send es un método ruby (sin rieles) que permite invocar otro método por su nombre.
De la documentación
http://corelib.rubyonrails.org/classes/Object.html#M001077
fuente
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:
Para asignar atributos con regularidad, se necesitaría
O usando el método .send:
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
fuente
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á.
Sin embargo, puede
send
las cadenas al objeto:fuente
define_method
: apidock.com/ruby/Module/define_method .¿Qué hace enviar?
send
es otra forma de llamar a un método.Esto se ilustra mejor con un ejemplo:
Envía vidas en la clase Objeto .
¿Cuál es el beneficio de esto?
El beneficio de este enfoque es que puede pasar el método que desea llamar como parámetro. He aquí un ejemplo sencillo:
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.fuente
Otro caso de uso para las vistas:
Permitir. que escriba una vista escalable que trabaje con todo tipo de objetos con:
fuente