Next: Looking at objects, Previous: Simple errors, Up: Debugging
Type the following lines:
x := Dictionary new x at: 1
The error you receive will look like:
Dictionary new: 31 "<0x33788>" error: key not found
…blah blah…
Dictionary>>#error:
[] in Dictionary>>#at:
[] in Dictionary>>#at:ifAbsent:
Dictionary(HashedCollection)>>#findIndex:ifAbsent:
Dictionary>>#at:ifAbsent:
Dictionary>>#at:
UndefinedObject(Object)>>#executeStatements
The error itself is pretty clear; we asked for something
within the Dictionary which wasn’t there. The object
which had the error is identified as Dictionary new: 31
.
A Dictionary’s default size is 31; thus, this is the object
we created with Dictionary new
.
The stack backtrace shows us the inner structure of how
a Dictionary responds to the #at:
message. Our hand-entered
command causes the usual entry for UndefinedObject(Object)
.
Then we see a Dictionary object responding to an #at:
message
(the “Dictionary>>#at:” line). This code called the object
with an #at:ifAbsent:
message. All of a sudden,
Dictionary calls that strange method #findIndex:ifAbsent:
,
which evaluates two blocks, and then the error happens.
To understand this better, it is necessary to know that
a very common way to handle errors in Smalltalk is to
hand down a block of code which will be called when an error
occurs. For the Dictionary code, the at:
message passes
in a block of code to the at:ifAbsent: code to be called
when at:ifAbsent:
can’t find the given key, and
at:ifAbsent:
does the same with findIndex:ifAbsent:
.
Thus, without even looking at the code for Dictionary itself, we can
guess something of the code for Dictionary’s implementation:
findIndex: key ifAbsent: errCodeBlock [ …look for key… (keyNotFound) ifTrue: [ ^(errCodeBlock value) ] … ] at: key [ ^self at: key ifAbsent: [^self error: 'key not found'] ]
Actually, findIndex:ifAbsent:
lies in class HashedCollection
,
as that Dictionary(HashedCollection)
in the backtrace says.
It would be nice if each entry on the stack backtrace included source line numbers. Unfortunately, at this point GNU Smalltalk doesn’t provide this feature. Of course, you have the source code available...
Next: Looking at objects, Previous: Simple errors, Up: Debugging