Що &method(:function)означає? Наприклад, у мене є такий рядок:
res = integrate(0, 1, a, &method(:function))
Що &method(:function)означає? Наприклад, у мене є такий рядок:
res = integrate(0, 1, a, &method(:function))
Відповіді:
Скажіть, у нас є метод
def add_one(num)
num + 1
end
і масив рядків
arr = ["1", "2"]
Ми хочемо mapперерахувати рядки рядків до їх відповідних виходів add_one.
Для початку ми можемо зателефонувати
nums = arr.map(&:to_i)
Це те саме, що і
nums = arr.map do |str|
str.to_i
end
Ви можете побачити, що означає карта (&: name) у Ruby? для отримання додаткової інформації про це.
Однак телефонувати не вдасться:
nums.map(&:add_one)
Чому? Тому що числа не мають вбудованого методу add_one. Так ви отримаєте NoMethodError.
Отже, замість того, щоб вказати лише ім'я методу, :add_one ви можете передати зв'язаний метод method(:add_one) :
nums.map(&method(:add_one))
Тепер, замість того, щоб кожне число використовувалося як приймач для add_oneметоду, вони будуть використовуватися як аргументи . Отже, це по суті те саме, що:
nums.map do |num|
add_one(num)
end
Щоб навести ще один приклад, порівняйте наступне:
[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#methodповертає пов'язане Method , а не an UnboundMethod. Метод прив’язаний до приймача, оскільки ви викликаєте його в екземплярі, і таким чином він знає, що selfтаке, тоді як Module#instance_methodповертає, UnboundMethodоскільки він не може знати, з яким екземпляром він буде використовуватися.
.instance_methodтому що я щойно проходив (помилково) пам’яті
method(:function)являє собою повідомлення, що надсилається (іноді його називають викликом методу ) до неявного приймача (тобто self). Він передає повідомлення methodнеявному приймачу (тобто self), передаючи :functionяк єдиний аргумент.
:functionє Symbolбуквальним, тобто це буквальне позначення a Symbol. Symbolце тип даних, що представляє "ім'я чогось".
&Одинарний префікс ampersand оператор "розкручує" a Procв блок . Тобто це дозволяє пройти Procтуди, де очікується блок . Якщо об'єкт ще не a Proc, йому буде надіслано to_procповідомлення, що дозволяє йому перетворити себе в a Proc. (Оператор є законним лише у списку аргументів і лише для останнього аргументу. Це дуал &сигілу в списку параметрів, який "перекочує" блок в Procоб'єкт.)
Procце тип даних, що представляє виконуваний код. Це основний бібліотечний клас Ruby для першокласних підпрограм.
Отже, що це робить, це викликати methodметод на selfз в :functionякості аргументу, виклик to_procна повернутому значенні, «розкачати» в результаті Procоб'єкта в блок і передати цей блок на заклик , integrateяк якщо б ви написали що - щось на зразок
res = integrate(0, 1, a) do
# something
end
methodМетод тут, швидше за все, Object#methodметод, який повертає пов'язаний Method об'єкт.
Отже, загалом це дещо рівнозначно
res = integrate(0, 1, a) do |*args, &block|
function(*args, &block)
end
Але виражається в тому, що зазвичай називають точковим стилем .