If I have a multidimensional array, I can exceed the bounds in the final dimension and get a nil return, but if I exceed the bounds of a non-final dimension, I receive an error. Is this by design, and if so what is the reasoning?
> ar = [ [00,01,02], [10,11,12], [20,21,22] ]
=> [[0, 1, 2], [10, 11, 12], [20, 21, 22]]
> ar[2][2]
=> 22
> ar[2][3]
=> nil
> ar[3][2]
NoMethodError: undefined method `[]' for nil:NilClass
from (irb):32
from :0
I understand why this is happening, but why isn’t nil[] defined to return nil?
I don’t know if Matz ever documented why the
NilClassis designed the way it is. If it’s not so then we can only guess. My guess is that it is based on the behavior of Smalltalk.nilcould either be message eating or exception throwing. Ruby has an exception throwing nil object.If you have a message eating nil then it’s difficult to determine the object that was the first one to return nil in a chained call like
arr[1][2][3]. I don’t know how often this really is an issue but it seems to be a valid point. As a counterexample Objective-C seems to do just fine with a message eating nil.You can patch
NilClassto become message eatingor for arrays only
both makes
nil[]return a nil and either can break existing code