Скажем, вы изменили базовое условие на return 0 if num.zero?
, затем вызов его с аргументом 3 будет выглядеть так:
1 + rcall(2)
# => 1 + rcall(1)
# => 1 + rcall(0)
# => 0
, что, если вы замените вызовы rcall
их результатами (начиная сснизу), выходит на 1 + 1 + 1 + 0
Другими словами, вы можете понять это немного легче, перейдя от базового случая вверх:
rcall(0)
# 0
rcall(1)
# the same as 1 + rcall(0), which is one
rcall(2)
# the same as 1 + rcall(1), which is two.
Надеюсь, вы увидите шаблон.
Как уже упоминалось в комментариях, вы можете оптимизировать его следующим образом:
RubyVM::InstructionSequence.compile_option = {
tailcall_optimization: true,
trace_instruction: false
}
def rcall(num, sum=0)
return sum if 10 == num
rcall(num - 1, sum + 1)
end
Хотя для этого могут потребоваться другие настройки, я не совсем уверен.
См. Что такое оптимизация Tail Call?