Rozumiem koncepcję, some_instance.send
ale próbuję dowiedzieć się, dlaczego można to nazwać w obie strony. Ruby Koans sugeruje, że istnieje jakiś powód, dla którego nie można zapewnić wielu różnych sposobów zrobienia tego samego. Oto dwa przykłady użycia:
class Foo
def bar?
true
end
end
foo = Foo.new
foo.send(:bar?)
foo.__send__(:bar?)
Czy ktoś ma o tym pojęcie?
__send__
, niesend
.public_send
, co często jest lepsze niż isend
tak.Jeśli naprawdę trzeba
send
zachowywać się jak to zwykle zrobić, należy użyć__send__
, ponieważ nie będzie (nie powinien) być nadpisane. Używanie__send__
jest szczególnie przydatne w metaprogramowaniu, gdy nie wiesz, jakie metody definiuje manipulowana klasa. Mogło się zepsućsend
.Zegarek:
Jeśli zastąpisz
__send__
, Ruby wyemituje ostrzeżenie:Niektóre przypadki, w których warto przesłonić,
send
to takie, w których ta nazwa jest odpowiednia, na przykład przekazywanie wiadomości, klasy gniazd itp.źródło
__send__
istnieje, więc nie można go przypadkowo nadpisać.Jak, dlaczego
send
istnieje: Nie mogę mówić za kogoś innego, aleobject.send(:method_name, *parameters)
wygląda ładniej niżobject.__send__(:method_name, *parameters)
, więc używamsend
, chyba że trzeba użyć__send__
.źródło
Oprócz tego, co powiedzieli ci inni i co sprowadza się do powiedzenia tego
send
i__send__
są to dwa aliasy tej samej metody, możesz być zainteresowany trzecią, nieco inną możliwością, czylipublic_send
. Przykład:Aktualizacja: Od Ruby 2.1
Module#include
iModule#extend
metody stały się publiczne, więc powyższy przykład już nie zadziała.źródło
Główna różnica między send
__send__
, i public_send jest następująca.__send__
są technicznie takie same, jak używane do wywołania metody Object, ale główna różnica polega na tym, że możesz przesłonić metodę wysyłania bez żadnego ostrzeżenia, a kiedy nadpisujesz,__send__
pojawia się komunikat ostrzegawczyDzieje się tak, ponieważ aby uniknąć konfliktów, szczególnie w klejnotach lub bibliotekach, gdy kontekst, w którym zostanie użyty, jest nieznany, zawsze używaj
__send__
zamiast wysyłania.__send__
) i public_send polega na tym, że send /__send__
can wywołać metody prywatne obiektu, a public_send nie może.Na koniec spróbuj użyć public_send, aby uniknąć bezpośredniego wywołania metody prywatnej zamiast używania __send__ lub send.
źródło