Co &method(:function)znaczy Na przykład mam tę linię:
res = integrate(0, 1, a, &method(:function))
Co &method(:function)znaczy Na przykład mam tę linię:
res = integrate(0, 1, a, &method(:function))
Odpowiedzi:
Powiedzmy, że mamy metodę
def add_one(num)
num + 1
end
i tablica ciągów
arr = ["1", "2"]
Chcemy maplistę ciągów odpowiadających im danych wyjściowychadd_one .
Na początek możemy zadzwonić
nums = arr.map(&:to_i)
To jest to samo co
nums = arr.map do |str|
str.to_i
end
Możesz zobaczyć Co oznacza mapa (i: nazwa) w Ruby? po więcej informacji na ten temat.
Jednak nie zadzwoni:
nums.map(&:add_one)
Dlaczego? Ponieważ liczby nie mają wbudowanej metody add_one. Więc dostaniesz NoMethodError.
Zamiast podawać tylko nazwę metody :add_one , możesz przekazać powiązaną metodę method(:add_one) :
nums.map(&method(:add_one))
Teraz, zamiast każdego num używany jako odbiornik dla add_onesposobu, będą one używane jako argumenty . Jest to zasadniczo to samo, co:
nums.map do |num|
add_one(num)
end
Aby podać inny przykład, porównaj następujące:
[1].map(&:puts)
# this is the same as [1].map { |num| num.puts }
# it raises NoMethodError
[1].map(&method(:puts))
# this is the same as [1].map { |num| puts num }
# it prints 1 successfully
Object#methodzwraca powiązane Method , a nie an UnboundMethod. Metoda jest powiązana z odbiornikiem, ponieważ wywołujesz ją w instancji, a zatem wie, co selfjest, podczas gdy Module#instance_methodzwraca a, UnboundMethodponieważ nie może wiedzieć, z którą instancją będzie używana.
.instance_methodponieważ właśnie przechodziłem przez (wadliwą) pamięć
method(:function)to wiadomość wysyłana (czasami nazywana wywołaniem metody ) do niejawnego odbiorcy (tj self.). Wysyła wiadomość methoddo niejawnego odbiorcy (tjself ), Przekazując :functionjako jedyny argument.
:function jest Symbol dosłowne, tzn. jest dosłowne oznaczenie Symbol. Symbolto typ danych reprezentujący „nazwę czegoś”.
Jednoargumentowy znak ampersand &operator „rozwija” a Procdo bloku . To znaczy, że możesz przejść tam, Procgdzie oczekiwany jest blok . Jeśli obiekt nie jest już a Proc, zostanie wysłany to_prockomunikat umożliwiający jego konwersję na Proc. (Operator jest dozwolony tylko na liście argumentów i tylko dla ostatniego argumentu. Jest podwójny z& podwójność sigil na liście parametrów, która „zwija” blok w Procobiekt.)
Procjest typem danych reprezentującym kod wykonywalny. Jest to podstawowa klasa biblioteki Ruby dla podprogramów pierwszej klasy.
To, co to robi, to wywołanie methodmetody selfz :functionargumentem, wywołanie to_procwartości zwracanej, „rozwinięcie” wynikowego Procobiektu do bloku i przekazanie tego bloku do wywołania integratetak, jakbyś napisał coś w rodzaju
res = integrate(0, 1, a) do
# something
end
methodMetoda jest tu najprawdopodobniej, Object#methodmetoda, która zwraca bound Method obiektu.
Podsumowując, jest to nieco równoważne
res = integrate(0, 1, a) do |*args, &block|
function(*args, &block)
end
Ale wyrażone w tak zwanym stylu bez punktów .