{"record":{"id":"e5b50fe7325f3e0b","repo":"krahets/hello-algo","slug":"index-out-of-bounds-e5b50f","errorCode":null,"errorMessage":"Index out of bounds","messagePattern":"Index out of bounds","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"en/codes/ruby/chapter_array_and_linkedlist/my_list.rb","lineNumber":23,"sourceCode":"=end\n\n### List class ###\nclass MyList\n  attr_reader :size       # Get list length (current number of elements)\n  attr_reader :capacity   # Get list capacity\n\n  ### Constructor ###\n  def initialize\n    @capacity = 10\n    @size = 0\n    @extend_ratio = 2\n    @arr = Array.new(capacity)\n  end\n\n  ### Access element ###\n  def get(index)\n    # If the index is out of bounds, throw an exception, as below\n    raise IndexError, \"Index out of bounds\" if index < 0 || index >= size\n    @arr[index]\n  end\n\n  ### Access element ###\n  def set(index, num)\n    raise IndexError, \"Index out of bounds\" if index < 0 || index >= size\n    @arr[index] = num\n  end\n\n  ### Add element at end ###\n  def add(num)\n    # When the number of elements exceeds capacity, trigger the extension mechanism\n    extend_capacity if size == capacity\n    @arr[size] = num\n\n    # Update the number of elements\n    @size += 1\n  end","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/en/codes/ruby/chapter_array_and_linkedlist/my_list.rb#L5-L41","documentation":"Raised by `MyList#get` (my_list.rb:23) when `index < 0 || index >= size`. This is a dynamic-array list implementation; the guard enforces that reads stay within the logical `[0, size)` range (not the underlying `@capacity`). It returns `@arr[index]`, so an out-of-range index would read uninitialized filler slots.","triggerScenarios":"Calling `list.get(i)` with `i` negative, `i >= list.size`, or `i` computed from an off-by-one loop. Also when `size` has been decremented by `remove` but the caller caches a stale index.","commonSituations":"Loop using `<= size` instead of `< size`; index from an external source not bounds-checked; stale index after a concurrent or sequential remove shifts elements.","solutions":["Validate `0 <= index && index < list.size` before calling `get`.","Use `list.size` (not capacity) as the upper bound in iteration.","Recompute or invalidate indices after `remove`/`insert`."],"exampleFix":"# before\nval = list.get(i)\n\n# after\nval = (0...list.size).include?(i) ? list.get(i) : nil","handlingStrategy":"validation","validationCode":"return nil unless (0...list.size).include?(index)\nlist.get(index)","typeGuard":"def valid_list_index?(list, index)\n  index.is_a?(Integer) && index >= 0 && index < list.size\nend","tryCatchPattern":"begin\n  list.get(index)\nrescue IndexError\n  nil\nend","preventionTips":["Bounds-check against list.size (logical length), not capacity.","Use exclusive upper bound (< size) in iteration, never <=.","Invalidate cached indices after insert/remove that shift elements."],"tags":["ruby","list","dynamic-array","index-bounds"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}