Что &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))
Теперь вместо каждого num, используемого в качестве получателя для 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 , а не UnboundMethod. Метод привязан к получателю, потому что вы вызываете его для экземпляра, и он, таким образом, знает, что selfесть, а Module#instance_methodвозвращает, UnboundMethodпотому что не может знать, с каким экземпляром он будет использоваться.
.instance_methodпотому что у меня просто (испорченная) память
method(:function)является отправкой сообщения (иногда называемого вызовом метода ) неявному получателю (то есть self). Он отправляет сообщение methodнеявному получателю (то есть self), передавая :functionв качестве единственного аргумента.
:functionявляется Symbolбуквальным, то есть это буквальное обозначение Symbol. Symbolтип данных, представляющий «имя чего-либо».
Оператор амперсанда с одинарным префиксом &«разворачивает» Procв блок . Т.е. он позволяет вам пройти там, Procгде ожидается блок . Если объект еще не является a Proc, ему будет отправлено to_procсообщение, позволяющее ему преобразовать себя в 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
Но выражается в том, что принято называть точечным стилем .