{"record":{"id":"2201bda92674710a","repo":"krahets/hello-algo","slug":"error-2201bd","errorCode":null,"errorMessage":"двусторонняя очередь пуста","messagePattern":"двусторонняя очередь пуста","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"ru/codes/ruby/chapter_stack_and_queue/array_deque.rb","lineNumber":76,"sourceCode":"  ### Извлечение из головы очереди ###\n  def pop_first\n    num = peek_first\n    # Указатель головы сдвигается на одну позицию назад\n    @front = index(@front + 1)\n    @size -= 1\n    num\n  end\n\n  ### Извлечение из хвоста очереди ###\n  def pop_last\n    num = peek_last\n    @size -= 1\n    num\n  end\n\n  ### Доступ к элементу в начале очереди ###\n  def peek_first\n    raise IndexError, 'двусторонняя очередь пуста' if is_empty?\n\n    @nums[@front]\n  end\n\n  ### Доступ к элементу в хвосте очереди ###\n  def peek_last\n    raise IndexError, 'двусторонняя очередь пуста' if is_empty?\n\n    # Вычислить индекс хвостового элемента\n    last = index(@front + size - 1)\n    @nums[last]\n  end\n\n  ### Вернуть массив для вывода ###\n  def to_array\n    # Преобразовывать только элементы списка в пределах фактической длины\n    res = []\n    for i in 0...size","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/ru/codes/ruby/chapter_stack_and_queue/array_deque.rb#L58-L94","documentation":"Raised by ArrayDeque#peek_first (ru) when the deque is empty. Because `pop_first` is implemented as `num = peek_first; @front = index(@front + 1); @size -= 1`, the SAME raise surfaces for both `peek_first` and `pop_first` on an empty deque. Note: unlike array_queue.push, the push methods here only `puts`+`return` on full — they never raise — so this is the only IndexError in the file.","triggerScenarios":"Calling `deque.peek_first` or `deque.pop_first` on an empty ArrayDeque (size 0), e.g. before any push, or after draining from both ends.","commonSituations":"A consumer loop that pops_first until empty then peeks; reading the front for display after a drain; mismatched push/pop counts in a driver block.","solutions":["Guard with `deque.is_empty?` before peek_first or pop_first.","Drive drain loops with `until deque.is_empty?`.","Use to_array (empty-safe) when you only need to inspect contents."],"exampleFix":"// before\ndeque.pop_first  # raises 'двусторонняя очередь пуста' when empty\n\n// after\nval = deque.is_empty? ? nil : deque.pop_first","handlingStrategy":"validation","validationCode":"val = deque.pop_first unless deque.is_empty?","typeGuard":"def deque_nonempty?(d) = !d.is_empty?","tryCatchPattern":"begin\n  val = deque.pop_first  # also covers peek_first\nrescue IndexError\n  val = nil\nend","preventionTips":["pop_first routes through peek_first — guard covers both.","Drive drain loops with `until deque.is_empty?`.","Note push_* only puts+returns on full — it never raises, so capacity is silent here."],"tags":["ruby","deque","circular-array","empty-state","index-error"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}