jibzoiderz jibzoiderz - 20 days ago 6
Ruby Question

undefined method `<' for nil:NilClass

While creating a bubble sort program i ran into this error:

test.rb:8:in `block in bubble_sort': undefined method `<' for nil:NilClass (NoMethodError)
from test.rb:6:in `downto'
from test.rb:6:in `bubble_sort'
from test.rb:16:in `<main>


does anyone know what does that mean? Here is the code:

def bubble_sort(arr)
length = arr.length
sorted = false


length.downto(0) do |cntr|

if arr[cntr] < arr[cntr + 1]

end


end
end

bubble_sort([2,6,8,1,0,2])

Answer

The error message undefined method '<' for nil:NilClass means that you are trying to call < on something that is nil.

In your example that must be the if arr[cntr] < arr[cntr + 1] comparison. In a next step we need to find out why arr[cntr] is nil. One reason could be that there is no element in the arr array at the cntr index, another reason might be that the index cntr is out of bounds of the array. In your example it is the second reason that is causing the problem.

Why is the index out of bounds? Let's have a closer look how the loop is build and use an example array [a, b, c] to do so:

length = arr.length              # length = 3             # [a, b, c].length
length.downto(0) do |cntr|       # 3.downto(0) do |cntr|
  if arr[cntr] < arr[cntr + 1]   #   if arr[3] < arr[4]   # in the first iteration

Ops, there aren't not indexes 3 and 4 in the arr array, because indexes start counting with 0 and there are only 3 elements in my example (that makes the last element's index 2).

The fix:

def bubble_sort(array)
  (array.length - 2).downto(0).each do |index|
    if array[index] < array[index + 1]
      # ...
    end
  end
end