Working on a version of Conway's Game of Life using 2d arrays and when trying too calculate the sum of each cell's "neighbors", I keeping getting blocked by the nil values.
def neighbor_count
grid.each_with_index do |row, idx|
row.each_with_index do |column, idx2|
[grid[idx - 1][idx2 - 1], grid[idx - 1][idx2], grid[idx - 1][idx2 + 1],
grid[idx][idx2 - 1], grid[idx][idx2], grid[idx][idx2 + 1],
grid[idx + 1][idx2 - 1], grid[idx + 1][idx2], grid[idx + 1][idx2 + 1]
].compact.sum
end
end
end
.compact seems to yield the most results if include "puts" in front of the array but none of the options I've tried give me 100%. I've tried reduce(:+), inject, .to_i, reject (to get rid of the nil values), and so forth.
What's missing here?
Error: world.rb:35:in block (2 levels) in neighbor_count': undefined method
[]' for nil:NilClass (NoMethodError)
Line 35 is the line above ].compact.sum
nil values are only a symptom of the illness. Don't treat the symptoms, get rid of the problem! Which is that you are violating array bounds.
.each_with_index
enumerates all indexes from the first to the last. And so idx + 1
on the last index will trigger this out-of-bounds situation. And idx - 1
on the first will produce an unexpected value instead of an error, which will impact your calculations. Good luck debugging that. :)
Put some guard checks in your code, to make sure you never go out of bounds.
Just to be absolutely clear, the problem is not that grid[idx + 1][idx2]
is nil and messes up your calculations. It is that grid[idx + 1]
is nil! And, naturally, you can't do nil[idx2]
. That's the error.