хорошие знания, спасибо!

имаю концепциюsome_instance.send но я пытаюсь понять, почему вы можете назвать это обоими способами. Рубиновые коаны подразумевают, что есть не только множество разных способов сделать то же самое. Вот два примера использования:

class Foo
  def bar?
    true
  end
end

foo = Foo.new
foo.send(:bar?)
foo.__send__(:bar?)

У кого-нибудь есть идеи по этому поводу?

Ответы на вопрос(4)

Решение Вопроса

класс сокетов стандартной библиотеки) определяют свои собственныеsend метод, который не имеет ничего общего сObject#send, Так что если вы хотите работать с объектами любого класса, вам нужно использовать__send__ быть на безопасной стороне.

Теперь это оставляет вопрос, почему естьsend и не только__send__, Если бы были только__send__ названиеsend могут быть использованы другими классами без путаницы. Причина в том, чтоsend существовал первым и только потом стало понятно, что названиеsend может также использоваться в других контекстах, поэтому__send__ был добавлен (это то же самое, что случилось сid а такжеobject_id Кстати).

 Andrew Marshall11 авг. 2014 г., 01:50
Также,BasicObject (введено в Ruby 1.9) имеет только__send__неsend.
 Marc-André Lafortune04 мар. 2016 г., 01:48
Хороший ответ. Может быть, даже лучше, если это упомянутоpublic_send, который часто предпочтительнееsend в любом случае.

что другие уже сказали вам, и что сводится к тому, чтобы сказать, чтоsend а также__send__ два псевдонима одного и того же метода, возможно, вас заинтересует третья, немного отличающаяся возможность,public_send, Пример:

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

Обновление: начиная с Ruby 2.1,Module#include а такжеModule#extend методы становятся общедоступными, поэтому приведенный выше пример больше не работает.

 jaydel26 июн. 2013 г., 15:42
хорошие знания, спасибо!

действительно нужноsend чтобы вести себя как обычно, вы должны использовать__send__потому что он не будет (не должен) переопределяться. С помощью__send__ особенно полезен в метапрограммировании, когда вы не знаете, какие методы определяет управляемый класс. Это могло бы переопределитьsend.

Часы:

class Foo
  def bar?
    true
  end

  def send(*args)
    false
  end
end

foo = Foo.new
foo.send(:bar?)
# => false
foo.__send__(:bar?)
# => true

Если вы переопределите__send__Руби выдаст предупреждение:

предупреждение: переопределение `__send__ 'может вызвать серьезные проблемы

В некоторых случаях было бы полезно переопределитьsend было бы там, где это имя подходит, например, передача сообщений, классы сокетов и т. д.

__send__ существует, поэтому он не может быть переписан случайно.

Почемуsend существует: я не могу говорить за кого-то еще, ноobject.send(:method_name, *parameters) выглядит лучше, чемobject.__send__(:method_name, *parameters)вот и пользуюсьsend если янужно использовать__send__.

Ваш ответ на вопрос