Entiendo el concepto de some_instance.send
pero estoy tratando de entender por qué puedes llamar a esto en ambos sentidos. Los Ruby Koans implican que hay alguna razón más allá de proporcionar muchas formas diferentes de hacer lo mismo. Aquí están los dos ejemplos de uso:
class Foo
def bar?
true
end
end
foo = Foo.new
foo.send(:bar?)
foo.__send__(:bar?)
Alguien tiene alguna idea sobre esto?
__send__
, nosend
.public_send
, que a menudo es preferible asend
todos modos.Si realmente necesita
send
comportarse como lo haría normalmente, debe usarlo__send__
, ya que no se anulará (no debería). El uso__send__
es especialmente útil en la metaprogramación, cuando no sabe qué métodos define la clase que se manipula. Podría haber anuladosend
.Reloj:
Si anula
__send__
, Ruby emitirá una advertencia:Algunos casos en los que sería útil anular
send
serían donde ese nombre es apropiado, como pasar mensajes, clases de socket, etc.fuente
__send__
existe, por lo que no se puede sobrescribir por accidente.En cuanto a por qué
send
existe: no puedo hablar por nadie más, pero seobject.send(:method_name, *parameters)
ve mejor queobject.__send__(:method_name, *parameters)
yo, así que lo uso asend
menos que necesite usarlo__send__
.fuente
Además de lo que otros ya le dijeron, y lo que se reduce a decir eso
send
y__send__
son dos alias del mismo método, es posible que le interese la tercera posibilidad, que es muy diferentepublic_send
. Ejemplo:Actualización: desde Ruby 2.1,
Module#include
y losModule#extend
métodos se hacen públicos, por lo que el ejemplo anterior ya no funcionaría.fuente
La principal diferencia entre send
__send__
, y public_send es la siguiente.__send__
son técnicamente los mismos que se usan para llamar al método de Object, pero la principal diferencia es que puede anular el método de envío sin ninguna advertencia y cuando lo anula__send__
, aparece un mensaje de advertenciaEsto se debe a que para evitar conflictos, especialmente en gemas o bibliotecas, cuando se desconoce el contexto en el que se usará, use siempre en
__send__
lugar de enviar.__send__
) y public_send es que send /__send__
can puede llamar a los métodos privados de un objeto y public_send no puede.Al final, intente usar public_send para evitar la llamada directa al método privado en lugar de usar __send__ o send.
fuente