{"record":{"id":"d88b36b0ad7243d6","repo":"krahets/hello-algo","slug":"error-d88b36","errorCode":null,"errorMessage":"ヒープが空です","messagePattern":"ヒープが空です","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"ja/codes/ruby/chapter_heap/my_heap.rb","lineNumber":83,"sourceCode":"\n  ### ノード i から下から上へヒープ化 ###\n  def sift_up(i)\n    loop do\n      # ノード i の親ノードを取得\n      p = parent(i)\n      # 「根ノードを越えた」または「ノードの修復が不要」になったらヒープ化を終了\n      break if p < 0 || @max_heap[i] <= @max_heap[p]\n      # 2 つのノードを交換\n      swap(i, p)\n      # ループで下から上へヒープ化\n      i = p\n    end\n  end\n\n  ### 要素をヒープから取り出す ###\n  def pop\n    # 空判定の処理\n    raise IndexError, \"ヒープが空です\" if is_empty?\n    # 根ノードと最も右の葉ノードを交換（先頭要素と末尾要素を交換）\n    swap(0, size - 1)\n    # ノードを削除\n    val = @max_heap.pop\n    # 上から下へヒープ化\n    sift_down(0)\n    # ヒープ先頭要素を返す\n    val\n  end\n\n  ### ノード i から上から下へヒープ化 ###\n  def sift_down(i)\n    loop do\n      # ノード i, l, r のうち値が最大のノードを ma とする\n      l, r, ma = left(i), right(i), i\n      ma = l if l < size && @max_heap[l] > @max_heap[ma]\n      ma = r if r < size && @max_heap[r] > @max_heap[ma]\n","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/ja/codes/ruby/chapter_heap/my_heap.rb#L65-L101","documentation":"Raised by MyMaxHeap#pop (ja/codes/ruby/chapter_heap/my_heap.rb:83) when the heap is empty. pop swaps the root with the last leaf and removes it, which is invalid when @max_heap has no elements, so the guard blocks it. Message is Japanese: \"Heap is empty\".","triggerScenarios":"Calling heap.pop when heap.is_empty? is true — before any push, or after extracting every element (e.g. heap-sort that drains the heap).","commonSituations":"Heap-sort / top-k routine that extracts one element too many; a priority-queue consumer that outran the producers; peeking/popping in a loop without an emptiness check.","solutions":["Check heap.is_empty? before pop.","Bound extract loops by the original size captured before draining.","Rescue IndexError around pop and treat empty as the normal completion of a drain."],"exampleFix":"# before\nwhile true\n  heap.pop # raises once drained\nend\n\n# after\nuntil heap.is_empty?\n  heap.pop\nend","handlingStrategy":"validation","validationCode":"heap.pop unless heap.is_empty?","typeGuard":"def heap_nonempty?(h); h.respond_to?(:is_empty?) && !h.is_empty?; end","tryCatchPattern":"begin\n  heap.pop\nrescue IndexError\n  nil\nend","preventionTips":["Check is_empty? before pop.","Capture the heap's size before a drain loop and bound extraction by it.","Treat empty as the normal end of heap-sort/top-k."],"tags":["ruby","heap","priority-queue","precondition","indexerror","i18n-japanese"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}