inject - это то же самое, что и Reduce, и аналогично уменьшению во многих других языках.
Существует несколько различных способов его вызова, но способ, показанный в вопросе,this:
inject(initial) { |memo, obj| block } → obj
Если вы укажете блок, то для каждого элемента в перечислении блоку передается значение аккумулятора (памятка) и элемент.Если вместо этого указать символ, то каждый элемент в коллекции будет передан в именованный метод memo.В любом случае результат становится новым значением для памятки.В конце итерации, последним значением memo является возвращаемое значение для метода.
Если вы явно не указали начальное значение для memo, тогда первый элемент коллекции используется в качестве начального значенияпамятки.
Итак, в вашем случае:
input.to_s.each_char.inject(0) do |sum, ch|
(sum << 8) ^ (ch.ord) ^ (sum >> 4)
end
Начальное значение суммы равно 0, которое используется для первой итерации, но для каждой последующей итерации результатблок используется для суммирования в следующей итерации.
Например, следующее должно выдавать то же значение без использования инжекта / уменьшения.
sum = 0
input.to_s.each_char do |ch|
sum = (sum << 8) ^ (ch.ord) ^ (sum >> 4)
end