2010-02-14 17 views
32

Możliwe duplikaty:
Ruby/Ruby on Rails ampersand colon shortcut
What does map(&:name) mean in Ruby?Co nazywasz operatorem &: w Ruby?

byłem czytanie StackOverflow i natknęliśmy się na poniższym kodzie

array.map(&:to_i) 

Ok, to łatwo zobaczyć, co ten kod robi ale chciałbym wiedzieć więcej oKonstrukcja, której nigdy wcześniej nie widziałem.

Niestety, wszystko, co mogę wymyślić, to "lambda", która nie jest. Google mówi mi, że składnia lambda w Ruby jest ->->(x,y){ x * y }

Więc każdy wie, co to tajemnicze &: jest i co może zrobić, z wyjątkiem wywoływania jednej metody?

+10

To dokładny duplikat * sześciu * różnych pytań. I proszę mi wierzyć, Ruby nie zmieniła * tego * dużo w ciągu ostatnich 8 dni, więc odpowiedzi * prawdopodobnie * będą takie same: http://StackOverflow.Com/questions/99318/, http: // StackOverflow .Com/questions/1217088 /, http://StackOverflow.Com/questions/1792683/, http://StackOverflow.Com/questions/1961030/, http://StackOverflow.Com/questions/2096975/, http://StackOverflow.Com/questions/2211751/. –

+5

Pewnie, teraz to wiem. Ale każdy nowy sposób sformułowania pomoże społeczności i tej stronie. W końcu ja * szukałem *, zanim zapytałem. – vava

+4

@vava To jest powód * nie usuwać * pytania. Twoje pytanie powinno nadal być zamknięte. –

Odpowiedz

61

Tutaj jest kilka ruchomych elementów, ale nazwa tego, co się dzieje, to konwersja Symbol#to_proc. Jest to część Ruby 1.9 i wyższej, i jest również dostępna, jeśli używasz późniejszych wersji Rails.

Po pierwsze, w Ruby, :foo oznacza "symbol foo", więc w rzeczywistości są to dwa oddzielne operatory, na które patrzysz, a nie jeden duży operator &:.

Kiedy mówisz foo.map(&bar), mówisz Ruby „wysłać wiadomość do obiektu foo aby wywołać metodę map z bloku I już zdefiniowane zwanego bar”. Jeśli bar nie jest już obiektem Proc, Ruby spróbuje to uczynić.

W tym przypadku nie przekazujemy w rzeczywistości bloku, ale zamiast niego został oznaczony symbol o nazwie bar. Ponieważ mamy domyślną konwersję to_proc dostępną na Symbol, Ruby widzi to i używa. Okazuje się, że ta konwersja wygląda następująco:

def to_proc 
    proc { |obj, *args| obj.send(self, *args) } 
end 

To sprawia, że ​​proc który wywołuje metodę o tej samej nazwie co symbolu. Składając to wszystko razem, używając oryginalnego przykład:

array.map(&:to_i) 

To wywołuje .map na tablicy i dla każdego elementu tablicy, zwraca wynik wywołania to_i na tym elemencie.

+7

mapa (i: to_i) jest dokładnie taka sama jak mapa {| x | x.to_i}. Ponieważ mapa wymaga bloku, a od rubinu 1.9, konwersja Symbol to_proc jest niejawnie dostępna. – Abhaya

Powiązane problemy