Czy to cała linia kodu? To znaczy, czy nie ma nic przed „wysłaniem”?
żyrafa
Odpowiedzi:
107
send wysyła komunikat do instancji obiektu i jego przodków w hierarchii klas, dopóki jakaś metoda nie zareaguje (ponieważ jej nazwa pasuje do pierwszego argumentu).
Praktycznie rzecz biorąc, te wiersze są równoważne:
1.send'+',21.+(2)1+2
Zauważ, że sendpomija sprawdzanie widoczności, więc możesz wywoływać również metody prywatne (przydatne do testowania jednostkowego).
Jeśli tak naprawdę nie ma zmiennej przed wysłaniem, oznacza to, że używany jest obiekt globalny:
Rozumiem, więc można by użyć send, gdyby ktoś chciał zapisać w bazie danych coś takiego jak 1. miesiąc, zamiast statycznego podawania liczby dni.
Christian Bankester
3
To prawda, możesz go użyć do wywołania metody z obliczonymi nazwami, a nie statycznymi. (Nie powinieneś jednak zezwalać na nieograniczone wprowadzanie danych przez użytkownika, aby uniknąć wywoływania metod prywatnych ... Możesz jednak nadać im unikalny prefiks: send 'user_method _' + nazwa metody, * args)
giraff
2
Dobry przypadek użycia może być taki, że chcesz przetestować metodę klasy chronionej, możesz wywołać ją poza klasą - w pliku testowym ..
GN.
108
send jest metodą ruby (bez szyn) pozwalającą na wywołanie innej metody po nazwie.
Świetna odpowiedź, wyraźniejsza niż pełna, zaakceptowana odpowiedź.
kodowanie aaron
63
Myślę, że jedną z najbardziej przydatnych funkcji metody .send jest to, że może ona dynamicznie wywoływać metodę. Może to zaoszczędzić wiele pisania. Jednym z najpopularniejszych zastosowań metody .send jest dynamiczne przypisywanie atrybutów. Na przykład:
classCar
attr_accessor :make,:model,:year
end
Aby regularnie przypisywać atrybuty, należałoby to zrobić
c =Car.new
c.make="Honda"
c.model="CRV"
c.year="2014"
Użycie .send w ten sposób dodaje niepotrzebnej złożoności i ułatwia nieumyślne wprowadzenie błędu do kodu. Na przykład w powyższym kodzie, jeśli dodasz nowy wpis do skrótu parametrów (taki jak „cylindry”), kod zakończy się niepowodzeniem z niezdefiniowanym błędem metody.
Kevin Schwerdtfeger
1
odpowiedzi na? w razie potrzeby można by użyć do zapobiegania takim błędom.
Richard_G
1
To było świetne wyjaśnienie! Dzięki Jha!
Sharath
1
@Kevin masz rację, ale czasami może to być konieczne. Większa elastyczność wiąże się z większym ryzykiem, które można złagodzić.
Dzięki! To jest dokładnie odpowiedź, której szukam. Zastanawiasz się, czy jest to powszechnie używane? Natknąłem się na coś podobnego w starym kodzie, nie jestem pewien, czy powinienem się tego trzymać. @ Mike Vallano
B Liu
1
@ b-liu Widziałem, że jest on używany przez doświadczonych programistów w nowym kodzie. Może być również pomocny przy korzystaniu z define_method: apidock.com/ruby/Module/define_method .
Mike Vallano
Niesamowite! Dzięki! @MikeVallano
B Liu
4
Co robi wysyłanie?
send to inny sposób na wywołanie metody.
Najlepiej ilustruje to przykład:
o =Object.new
o.send(:to_s)# => "#<Object:0x00005614d7a24fa3>"# is equivalent to:
o.to_s # => "#<Object:0x00005614d7a24fa3>"
Zaletą tego podejścia jest to, że jako parametr można przekazać metodę, którą chcesz wywołać. Oto prosty przykład:
def dynamically_call_a_method(name)
o =Object.new
o.send name
end
dynamically_call_a_method(:to_s)# => "#<Object:0x00005614d7a24fa3>"
Możesz przekazać metodę, którą chcesz wywołać. W tym przypadku przeszliśmy :to_s. Może to być bardzo przydatne przy metaprogramowaniu w języku ruby, ponieważ pozwala nam to wywoływać różne metody zgodnie z naszymi różnymi wymaganiami.
Odpowiedzi:
send
wysyła komunikat do instancji obiektu i jego przodków w hierarchii klas, dopóki jakaś metoda nie zareaguje (ponieważ jej nazwa pasuje do pierwszego argumentu).Praktycznie rzecz biorąc, te wiersze są równoważne:
Zauważ, że
send
pomija sprawdzanie widoczności, więc możesz wywoływać również metody prywatne (przydatne do testowania jednostkowego).Jeśli tak naprawdę nie ma zmiennej przed wysłaniem, oznacza to, że używany jest obiekt globalny:
źródło
send jest metodą ruby (bez szyn) pozwalającą na wywołanie innej metody po nazwie.
Z dokumentacji
http://corelib.rubyonrails.org/classes/Object.html#M001077
źródło
Myślę, że jedną z najbardziej przydatnych funkcji metody .send jest to, że może ona dynamicznie wywoływać metodę. Może to zaoszczędzić wiele pisania. Jednym z najpopularniejszych zastosowań metody .send jest dynamiczne przypisywanie atrybutów. Na przykład:
Aby regularnie przypisywać atrybuty, należałoby to zrobić
Lub używając metody .send:
Ale to wszystko można zastąpić następującymi:
Zakładając, że aplikacja Rails musi przypisać atrybuty do klasy samochodu na podstawie danych wejściowych użytkownika, możesz to zrobić
źródło
Inny przykład, podobny do https://stackoverflow.com/a/26193804/1897857 Antonio Jha
jest wtedy, gdy chcesz odczytać atrybuty obiektu.
Na przykład, jeśli masz tablicę ciągów, jeśli spróbujesz iterować przez nie i wywołać je na swoim obiekcie, to nie zadziała.
Możesz
send
jednak napisać ciągi do obiektu:źródło
define_method
: apidock.com/ruby/Module/define_method .Co robi wysyłanie?
send
to inny sposób na wywołanie metody.Najlepiej ilustruje to przykład:
Send żyje w klasie Object .
Jaka jest korzyść z tego?
Zaletą tego podejścia jest to, że jako parametr można przekazać metodę, którą chcesz wywołać. Oto prosty przykład:
Możesz przekazać metodę, którą chcesz wywołać. W tym przypadku przeszliśmy
:to_s
. Może to być bardzo przydatne przy metaprogramowaniu w języku ruby, ponieważ pozwala nam to wywoływać różne metody zgodnie z naszymi różnymi wymaganiami.źródło
Inny przypadek użycia widoków:
Dopuszczać . możesz napisać skalowalny widok, który pracuje z wszelkiego rodzaju obiektami z:
źródło