Я понимаю концепцию, some_instance.send
но я пытаюсь понять, почему вы можете назвать это обоими способами. Рубиновые коаны подразумевают, что есть не только множество разных способов сделать то же самое. Вот два примера использования:
class Foo
def bar?
true
end
end
foo = Foo.new
foo.send(:bar?)
foo.__send__(:bar?)
У кого-нибудь есть идеи по этому поводу?
__send__
, нетsend
.public_send
, что часто предпочтительнее вsend
любом случае.Если вам действительно нужно
send
вести себя так, как обычно, вы должны использовать__send__
, потому что он не будет (не должен) переопределяться. Использование__send__
особенно полезно в метапрограммировании, когда вы не знаете, какие методы определяет управляемый класс. Это могло бы переопределитьsend
.Смотреть:
Если вы переопределите
__send__
, Ruby выдаст предупреждение:Некоторые случаи, когда было бы полезно переопределить
send
, когда это имя подходит, например, передача сообщений, классы сокетов и т. Д.источник
__send__
существует, поэтому он не может быть переписан случайно.Что касается того, почему
send
существует: я не могу говорить за кого-то еще, ноobject.send(:method_name, *parameters)
выглядит лучше, чемobject.__send__(:method_name, *parameters)
, поэтому я использую,send
если мне не нужно использовать__send__
.источник
Помимо того , что другие уже сказал вам, и то , что сводится к тому, что говорят
send
и__send__
будут два псевдонимами одного и того же метода, вы можете быть заинтересованы в третьих, somwhat другая возможность, котораяpublic_send
. Пример:Обновление: начиная с Ruby 2.1,
Module#include
иModule#extend
методы становятся общедоступными, поэтому приведенный выше пример больше не будет работать.источник
Основное различие между send
__send__
, и public_send заключается в следующем.__send__
технически аналогичны используемым для вызова метода Object, но главное отличие состоит в том, что вы можете переопределить метод send без какого-либо предупреждения, а при переопределении__send__
появляется предупреждающее сообщениеЭто связано с тем, что во избежание конфликтов, особенно в гемах или библиотеках, когда контекст, в котором он будет использоваться, неизвестен, всегда используйте
__send__
вместо send.__send__
) и public_send заключается в том, что send /__send__
может вызывать приватные методы объекта, а public_send - нет.В конце попытайтесь использовать public_send, чтобы избежать прямого вызова частного метода вместо использования __send__ или send.
источник