Je comprends le concept some_instance.send
mais j'essaie de comprendre pourquoi vous pouvez appeler cela dans les deux sens. Les Ruby Koans impliquent qu'il y a une raison au-delà de fournir de nombreuses façons différentes de faire la même chose. Voici les deux exemples d'utilisation:
class Foo
def bar?
true
end
end
foo = Foo.new
foo.send(:bar?)
foo.__send__(:bar?)
Quelqu'un a une idée à ce sujet?
__send__
, passend
.public_send
, ce qui est souvent préférable à desend
toute façon.Si vous avez vraiment besoin
send
de vous comporter comme d'habitude, vous devriez l'utiliser__send__
, car il ne sera pas (il ne devrait pas) être remplacé. L'utilisation__send__
est particulièrement utile dans la métaprogrammation, lorsque vous ne savez pas quelles méthodes la classe manipulée définit. Cela aurait pu être remplacésend
.Regarder:
Si vous remplacez
__send__
, Ruby émettra un avertissement:Certains cas où il serait utile de remplacer
send
seraient ceux où ce nom est approprié, comme le passage de messages, les classes de socket, etc.la source
__send__
existe donc il ne peut pas être écrasé par accident.Quant à savoir pourquoi
send
existe: je ne peux parler pour personne d'autre, maisobject.send(:method_name, *parameters)
ça a l'air plus beau queobject.__send__(:method_name, *parameters)
, donc j'utilisesend
sauf si j'ai besoin d'utiliser__send__
.la source
En dehors de ce que d'autres vous ont déjà dit, et ce qui revient à dire cela
send
et que ce__send__
sont deux alias de la même méthode, vous pourriez être intéressé par la troisième possibilité, quelque peu différente, qui estpublic_send
. Exemple:Mise à jour: Depuis Ruby 2.1
Module#include
et lesModule#extend
méthodes deviennent publiques, l'exemple ci-dessus ne fonctionnera plus.la source
La principale différence entre send
__send__
et public_send est la suivante.__send__
sont techniquement les mêmes que ceux utilisés pour appeler la méthode Object, mais la principale différence est que vous pouvez remplacer la méthode send sans aucun avertissement et lorsque vous remplacez,__send__
il y a un message d'avertissementEn effet, pour éviter les conflits, en particulier dans les gemmes ou les bibliothèques lorsque le contexte dans lequel il sera utilisé est inconnu, utilisez toujours
__send__
au lieu d'envoyer.__send__
) et public_send est que send /__send__
peut appeler les méthodes privées d'un objet, et public_send ne le peut pas.À la fin, essayez d'utiliser public_send pour éviter un appel direct à une méthode privée au lieu d'utiliser __send__ ou send.
la source