2013-08-04 22 views

Odpowiedz

7

Z fine manual:

send (symbol [, args ...]) → obj
send (string [, args ...]) → obj

Powoduje wywołanie metody identyfikowanej przez symbol, przekazując jej dowolne określone argumenty. [...] Gdy metoda jest identyfikowana przez ciąg, ciąg jest konwertowany na symbol.

i instance_eval:

instance_eval (string [, filename [, lineno]]) → obj
instance_eval {| | Blok} → obj

Ocenia łańcuch zawierający Ruby kodu źródłowego, lub bloku danych, w związku z odbiornikiem (obj). Aby ustawić kontekst, zmienna self jest ustawiana na obj podczas wykonywania kodu, dając kod dostępu do zmiennych instancji obj.

Więc send wykonuje metodę natomiast instance_eval wykonuje dowolny blok kodu (jako ciąg lub blok) z self zestaw do obiektu wywołującego, że jesteś na instance_eval.

W twoim przypadku nie ma dużej różnicy, ponieważ ciąg, który podajesz instance_eval, jest tylko jedną metodą. Główną różnicą jest to, że każdy, kto czyta twój kod (łącznie z tobą w ciągu sześciu miesięcy) będzie się zastanawiał, dlaczego używasz instance_eval do wywoływania pojedynczej metody.

Możesz być także zainteresowany Object#public_send i BasicObject#__send__

+1

Świetnie, już się zastanawiam, dlaczego miałem jedną metodę dla 'instance_eval'. –

5

Cokolwiek można zrobić z send jest właściwym podzbiorem że od instance_eval. Mianowicie, argument do send musi być pojedynczą metodą (i jej argumentami), podczas gdy argument do instance_method jest arbitralnym kodem. Zawsze, gdy masz send, możesz przepisać je na instance_eval, ale nie na odwrót.

Jednak performancewise, send jest znacznie szybsze niż instance_eval, ponieważ nie ma dodatkowych parsowanie wymagane do wykonywania send, natomiast instance_eval potrzeby analizować cały argument.

W twoim przykładzie wynik będzie taki sam, ale pierwszy będzie działał szybciej.

+1

Przyjemne podsumowanie, a dostałem bonus o wydajności! –

Powiązane problemy