Ruby: слишком глубокий уровень стека (SystemStackError) maxlimit

avatar
lokanadham100
8 апреля 2018 в 05:36
140
1
4

Вот мой пример кода:

def test(v)
  test(v-1) if v > 0
  p v
end

если я позвоню test(11893), он работает нормально. если у меня есть v > 11893, он выдает SystemStackError. Как увеличить лимит этой ошибки?

Источник

Ответы (1)

avatar
Aleksei Matiushkin
8 апреля 2018 в 05:50
6

MRI имеет хвостовую рекурсию оптимизацию отключенную по умолчанию. Но можно включить:

RubyVM::InstructionSequence.compile_option = {
  tailcall_optimization: true,
  trace_instruction: false
}

также сам код должен использовать хвостовую рекурсию:

def test(v)
  return unless v > 0
  p v
  test(v-1) 
end
Aaron Christiansen
8 апреля 2018 в 09:58
0

Знаете ли вы, есть ли конкретная причина, по которой он отключен по умолчанию?

Aleksei Matiushkin
8 апреля 2018 в 10:18
1

@AaronChristiansen нет, к сожалению, понятия не имею. Дикая догадка была бы такой: либо это все еще экспериментально, либо «ruby — это не рекурсия».

Cary Swoveland
8 апреля 2018 в 17:43
1

Ссылка включить содержит короткий раздел "Отрицательная сторона совокупной стоимости владения?" который содержит: «Гвидо ван Россум написал о том, почему он против поддержки TCO в Python. Одна из основных проблем, на которую он указывает, заключается в том, что TCO искажает трассировку стека и, следовательно, затрудняет отладку». За этим следует «...Matz менее против этой идеи... Ruby позволяет вам включить ее по желанию...».