{"record":{"id":"c215ec3e66d29716","repo":"krahets/hello-algo","slug":"error-c215ec","errorCode":null,"errorMessage":"雙向佇列為空","messagePattern":"雙向佇列為空","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"zh-hant/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/zh-hant/codes/ruby/chapter_stack_and_queue/array_deque.rb#L58-L94","documentation":"Raised by peek_first of the ArrayDeque teaching class (a circular-array double-ended queue) when is_empty? is true. It prevents reading from @nums[@front] when the deque holds zero elements, which would return stale or zero data. The guard fires before any array read.","triggerScenarios":"Calling deque.peek_first on a newly constructed deque (size 0), calling it after all elements have been popped, or calling pop_first (which internally calls peek_first) on an empty deque.","commonSituations":"Assuming the deque has elements after a failed push (push_first/push_last silently print '已滿' instead of raising); draining the deque then peeking; using peek as a default value without an emptiness guard.","solutions":["Check deque.is_empty? before calling peek_first or pop_first.","Return a default value when empty: deque.is_empty? ? nil : deque.peek_first.","Track push/pop counts externally to detect state mismatches.","Note that push_first/push_last do NOT raise on full — they print and return nil — so verify the push succeeded before relying on peek."],"exampleFix":"# before\nfirst = deque.peek_first  # raises if deque was drained\n\n# after\nfirst = deque.is_empty? ? nil : deque.peek_first","handlingStrategy":"validation","validationCode":"return nil if deque.is_empty?\ndeque.peek_first","typeGuard":"# Ruby: safe peek_first\ndef safe_peek_first(deque)\n  deque.is_empty? ? nil : deque.peek_first\nend","tryCatchPattern":"begin\n  first = deque.peek_first\nrescue IndexError\n  first = nil\nend","preventionTips":["Check is_empty? before peek_first or pop_first.","Note that push_first silently no-ops when full (prints to stdout, no raise) — verify size increased.","Drain with 'until deque.is_empty?' rather than a fixed count."],"tags":["ruby","index-error","data-structures","deque","empty-state","circular-array"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}