variable objects for example ruby syntax

objects - Ruby send vs__send__



ruby>= (4)

Algunas clases (por ejemplo, la clase de socket de la biblioteca estándar) definen su propio método de send que no tiene nada que ver con Object#send . Entonces, si quieres trabajar con objetos de cualquier clase, necesitas usar __send__ para estar seguro.

Ahora que deja la pregunta, por qué hay send y no solo __send__ . Si solo __send__ el __send__ del nombre podría ser utilizado por otras clases sin confusión. La razón es que el send existió primero y solo más tarde se supo que el send del nombre también podría ser útil en otros contextos, por __send__ se agregó __send__ (es lo mismo que sucedió con id y object_id por cierto).

Entiendo el concepto de some_instance.send pero estoy tratando de averiguar por qué puedes llamar esto en ambos sentidos. Los Ruby Koans implican que hay alguna razón más allá de proporcionar muchas maneras 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?


Aparte de lo que otros ya te dijeron, y lo que se reduce a decir que send y __send__ son dos alias del mismo método, puede que te interese la tercera posibilidad, algo diferente, que es public_send . Ejemplo:

A, B, C = Module.new, Module.new, Module.new B.include A #=> error -- private method B.send :include, A #=> bypasses the method''s privacy C.public_send :include, A #=> does not bypass privacy

Actualización: Dado que los métodos de Module#extend Ruby 2.1, Module#include y Module#extend hacen públicos, el ejemplo anterior ya no funcionaría.


Si realmente necesita send para comportarse como lo haría normalmente, debería usar __send__ , porque no será (no debería) anulado. Usar __send__ es especialmente útil en la metaprogramación, cuando no sabes qué métodos define la clase que se está manipulando. Podría haber send .

Reloj:

class Foo def bar? true end def send(*args) false end end foo = Foo.new foo.send(:bar?) # => false foo.__send__(:bar?) # => true

Si anula __send__ , Ruby emitirá una advertencia:

advertencia: redefinir `__send__ ''puede causar problemas graves

Algunos casos en los que sería útil sobrescribir el send serían aquellos en los que ese nombre sea apropiado, como el send mensajes, las clases de socket, etc.


__send__ existe por lo que no se puede __send__ por accidente.

En cuanto a por qué existe el send : no puedo hablar por nadie más, pero object.send(:method_name, *parameters) ve mejor que el object.__send__(:method_name, *parameters) , entonces uso send menos que necesite usar __send__ .