{"record":{"id":"edb9393b04e079b4","repo":"krahets/hello-algo","slug":"error-edb939","errorCode":null,"errorMessage":"双向队列为空","messagePattern":"双向队列为空","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"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/codes/ruby/chapter_stack_and_queue/array_deque.rb#L58-L94","documentation":"Raised by `ArrayDeque#peek_first` (array_deque.rb:76) when `is_empty?` is true. `peek_first` reads `@nums[@front]` to expose the front element without removing it; on an empty deque `@front` is stale and `@size` is zero, so the read would return garbage or nil. The guard ensures callers never see an uninitialized slot.","triggerScenarios":"Calling `deque.peek_first` (or `pop_first`, which delegates to it) on a deque whose `@size == 0`. Occurs after draining all elements, or immediately after construction before any push.","commonSituations":"Deque used as a sliding-window buffer that gets fully consumed between batches; calling peek before the first enqueue; off-by-one in a consume loop.","solutions":["Check `deque.is_empty?` before calling `peek_first` or `pop_first`.","Use `deque.size.zero?` explicitly if readability matters.","If empty peek is a normal control-flow signal, rescue IndexError at the call site."],"exampleFix":"# before\nfront = deque.peek_first\n\n# after\nfront = deque.is_empty? ? nil : deque.peek_first","handlingStrategy":"validation","validationCode":"return nil if deque.is_empty?\ndeque.peek_first","typeGuard":"def deque_readable?(deque)\n  deque.respond_to?(:is_empty?) && deque.respond_to?(:peek_first) && !deque.is_empty?\nend","tryCatchPattern":"begin\n  deque.peek_first\nrescue IndexError\n  nil\nend","preventionTips":["Check is_empty? before peek_first or pop_first.","Track remaining element count externally when the deque is shared.","Treat nil as the empty sentinel in caller logic."],"tags":["ruby","deque","precondition","empty-state"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}