krahets/hello-algo · error · IndexError
索引越界
Error message
索引越界
What it means
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.
Source
Thrown at zh-hant/codes/ruby/chapter_array_and_linkedlist/my_list.rb:23
=end
### 串列類別 ###
class MyList
attr_reader :size # 獲取串列長度(當前元素數量)
attr_reader :capacity # 獲取串列容量
### 建構子 ###
def initialize
@capacity = 10
@size = 0
@extend_ratio = 2
@arr = Array.new(capacity)
end
### 訪問元素 ###
def get(index)
# 索引如果越界,則丟擲異常,下同
raise IndexError, "索引越界" if index < 0 || index >= size
@arr[index]
end
### 訪問元素 ###
def set(index, num)
raise IndexError, "索引越界" if index < 0 || index >= size
@arr[index] = num
end
### 在尾部新增元素 ###
def add(num)
# 元素數量超出容量時,觸發擴容機制
extend_capacity if size == capacity
@arr[size] = num
# 更新元素數量
@size += 1
endView on GitHub (pinned to 69932aed18)
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.
Example fix
# before
val = list.get(i) # crashes when i == list.size in an inclusive loop
# after
val = (0...list.size).map { |i| list.get(i) } # exclusive range, never hits size Defensive patterns
Strategy: validation
Validate before calling
return nil unless index >= 0 && index < list.size val = list.get(index)
Type guard
# Ruby: guard method for safe access def safe_get(list, index) (index.is_a?(Integer) && index >= 0 && index < list.size) ? list.get(index) : nil end
Try / catch
begin val = list.get(index) rescue IndexError => e # handle out-of-bounds: log, use default, or re-raise with context val = nil end
Prevention
- 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).
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13).
Data as JSON: /api/errors/ce9f925afe8adff3.
Report an issue: GitHub.