krahets/hello-algo · error · IndexError

雙向佇列為空

Error message

雙向佇列為空

What it means

Raised by the private pop(is_front) method of the LinkedListDeque teaching class (a doubly-linked-list double-ended queue) when is_empty? is true. Both pop_first and pop_last delegate to this method, so attempting to dequeue from either end of an empty deque triggers it. The guard fires before any node pointer manipulation.

Source

Thrown at zh-hant/codes/ruby/chapter_stack_and_queue/linkedlist_deque.rb:70

      node.prev = @rear
      @rear = node # 更新尾節點
    end
    @size += 1 # 更新佇列長度
  end

  ### 佇列首入列 ###
  def push_first(num)
    push(num, true)
  end

  ### 佇列尾入列 ###
  def push_last(num)
    push(num, false)
  end

  ### 出列操作 ###
  def pop(is_front)
    raise IndexError, '雙向佇列為空' if is_empty?

    # 佇列首出列操作
    if is_front
      val = @front.val # 暫存頭節點值
      # 刪除頭節點
      fnext = @front.next
      unless fnext.nil?
        fnext.prev = nil
        @front.next = nil
      end
      @front = fnext # 更新頭節點
    # 佇列尾出列操作
    else
      val = @rear.val # 暫存尾節點值
      # 刪除尾節點
      rprev = @rear.prev
      unless rprev.nil?
        rprev.next = nil

View on GitHub (pinned to 69932aed18)

Solutions

  1. Check deque.is_empty? before calling pop_first or pop_last.
  2. Use while !deque.is_empty? to drain both ends safely.
  3. Return nil when empty: deque.is_empty? ? nil : deque.pop_first.
  4. Wrap in begin/rescue IndexError for defensive dequeue.

Example fix

# before
5.times { deque.pop_first }  # raises if fewer than 5 elements

# after
until deque.is_empty?
  deque.pop_first
end
Defensive patterns

Strategy: validation

Validate before calling

return nil if deque.is_empty?
deque.pop_first  # or pop_last

Type guard

# Ruby: safe pop from either end
def safe_pop_first(deque)
  deque.is_empty? ? nil : deque.pop_first
end

Try / catch

begin
  val = deque.pop_first
rescue IndexError
  val = nil
end

Prevention

When it happens

Trigger: Calling deque.pop_first or deque.pop_last on a new deque (size 0), calling them after all elements have been removed, or draining past empty in a loop.

Common situations: Unbalanced push/pop calls; assuming the deque has elements after construction; draining with a fixed count instead of an emptiness check.

Related errors


AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13). Data as JSON: /api/errors/232db764997669d4. Report an issue: GitHub.