Entendo o conceito de some_instance.send
mas estou tentando descobrir por que você pode chamar isso de duas maneiras. Os Ruby Koans sugerem que há alguma razão além de fornecer várias maneiras diferentes de fazer a mesma coisa. Aqui estão os dois exemplos de uso:
class Foo
def bar?
true
end
end
foo = Foo.new
foo.send(:bar?)
foo.__send__(:bar?)
Alguém tem alguma idéia sobre isso?
__send__
, nãosend
.public_send
, o que geralmente é preferível asend
qualquer forma.Se você realmente precisa
send
se comportar como faria normalmente, deve usá-__send__
lo, porque não será (não deveria) ser vencido. O uso__send__
é especialmente útil na metaprogramação, quando você não sabe quais métodos a classe que está sendo manipulada define. Poderia ter vencidosend
.Ver:
Se você substituir
__send__
, Ruby emitirá um aviso:Alguns casos em que seria útil substituir
send
seriam onde esse nome é apropriado, como passagem de mensagens, classes de soquete etc.fonte
__send__
existe para que não possa ser sobrescrito por acidente.Quanto à razão
send
existe: Eu não posso falar por ninguém, masobject.send(:method_name, *parameters)
parece mais agradável do queobject.__send__(:method_name, *parameters)
, então eu usosend
a menos que eu preciso usar__send__
.fonte
Além do que os outros já lhe disseram, e o que se resume a dizer isso
send
e__send__
são dois pseudônimos do mesmo método, você pode estar interessado na terceira possibilidade, que é diferentepublic_send
. Exemplo:Atualização: Desde o Ruby 2.1,
Module#include
e osModule#extend
métodos se tornam públicos, o exemplo acima não funcionaria mais.fonte
A principal diferença entre send
__send__
, e public_send é a seguinte.__send__
são tecnicamente iguais aos usados para chamar o método Object, mas a principal diferença é que você pode substituir o método send sem nenhum aviso e quando você o substitui__send__
, há uma mensagem de avisoIsso ocorre para evitar conflitos, especialmente em gemas ou bibliotecas, quando o contexto em que será usado é desconhecido, sempre use em
__send__
vez de enviar.__send__
) e public_send é que enviar /__send__
pode chamar os métodos privados de um objeto, e public_send não pode.No final, tente usar public_send para evitar a chamada direta ao método privado em vez de usar __send__ ou send.
fonte