{"record":{"id":"ce9f925afe8adff3","repo":"krahets/hello-algo","slug":"error-ce9f92","errorCode":null,"errorMessage":"索引越界","messagePattern":"索引越界","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"zh-hant/codes/ruby/chapter_array_and_linkedlist/my_list.rb","lineNumber":23,"sourceCode":"=end\n\n### 串列類別 ###\nclass MyList\n  attr_reader :size       # 獲取串列長度（當前元素數量）\n  attr_reader :capacity   # 獲取串列容量\n\n  ### 建構子 ###\n  def initialize\n    @capacity = 10\n    @size = 0\n    @extend_ratio = 2\n    @arr = Array.new(capacity)\n  end\n\n  ### 訪問元素 ###\n  def get(index)\n    # 索引如果越界，則丟擲異常，下同\n    raise IndexError, \"索引越界\" if index < 0 || index >= size\n    @arr[index]\n  end\n\n  ### 訪問元素 ###\n  def set(index, num)\n    raise IndexError, \"索引越界\" if index < 0 || index >= size\n    @arr[index] = num\n  end\n\n  ### 在尾部新增元素 ###\n  def add(num)\n    # 元素數量超出容量時，觸發擴容機制\n    extend_capacity if size == capacity\n    @arr[size] = num\n\n    # 更新元素數量\n    @size += 1\n  end","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/zh-hant/codes/ruby/chapter_array_and_linkedlist/my_list.rb#L5-L41","documentation":"Raised by the get(index) accessor of the MyList teaching class (a hand-written dynamic array) when the caller requests a slot outside the valid element range [0, size). The guard 'index < 0 || index >= size' fires before the underlying @arr is touched, preventing undefined reads. It uses Ruby's built-in IndexError so callers can rescue it with a standard exception type.","triggerScenarios":"Calling my_list.get(negative_number), calling get with an index equal to or greater than the current element count (my_list.size), or calling get on a freshly-constructed list (size == 0) with any index at all.","commonSituations":"Off-by-one loops using 0..size (inclusive) instead of 0...size (exclusive); confusing the backing array capacity with the logical element count; iterating a range that was computed against @arr.length rather than list.size; reading before any add() calls have populated the list.","solutions":["Validate the index before calling: use 'if index >= 0 && index < list.size' as a guard.","Use exclusive ranges (0...size) in iteration loops so the last valid index is size - 1, not size.","Check list.size or call a helper before get to short-circuit on empty lists.","Wrap the call in begin/rescue IndexError to handle the edge case gracefully when the index source is external or user-provided."],"exampleFix":"# before\nval = list.get(i)  # crashes when i == list.size in an inclusive loop\n\n# after\nval = (0...list.size).map { |i| list.get(i) }  # exclusive range, never hits size","handlingStrategy":"validation","validationCode":"return nil unless index >= 0 && index < list.size\nval = list.get(index)","typeGuard":"# Ruby: guard method for safe access\ndef safe_get(list, index)\n  (index.is_a?(Integer) && index >= 0 && index < list.size) ? list.get(index) : nil\nend","tryCatchPattern":"begin\n  val = list.get(index)\nrescue IndexError => e\n  # handle out-of-bounds: log, use default, or re-raise with context\n  val = nil\nend","preventionTips":["Always use exclusive ranges (0...size) when iterating indices for get.","Check list.size before accessing when the index comes from external input.","Distinguish size (logical element count) from capacity (backing array length)."],"tags":["ruby","index-error","bounds-check","data-structures","dynamic-array","off-by-one"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}