So I used an EsQueue. Because the number of objects the queue would hold will vary, I used ##new: to instantiate the queue. And, I ran into a nasty little anomaly when I happened to create an instance with a size of 1.
(Yes, I know EsQueue isn't marked as a public class, but why would I want to write a queue class, when one already exists in the image?)
Try the following code:
- Code: Select all
|q|
q := EsQueue new: 1.
q add: 1.
q remove.
q add: 2.
q remove.
You would expect the second ##remove to return the Integer 2, but instead it returns nil. In fact,
- Code: Select all
|q|
q := EsQueue new: 1.
q add: 1.
q add: 2.
q remove.
q remove.
q remove.
q remove.
returns nil from the 2nd, 3rd, and fourth invocations of #remove.
Instantiating with "EsQueue new" or any other positive integer valued size returns the expected value
and raises a "queue is empty" exception when you try to remove more objects than were put on
the queue.
Commenting out the primitives in ##add: and ##remove and stepping through, the problem appears
to be that ##grow doesn't actually grow a queue instantiated as size one, and unlike the smalltalk
source, the primitives don't raise an exception when attempting to add an object past the end of the
contents variable.
The simplest fix appears to be to change EsQueue>>size:
- Code: Select all
size: size
"Initialize the instance variables of the receiver."
head := tail := 1.
contents := Array new: (size max: 2)
This problem exists in, at least, versions 7.0.1 through the version 8 beta.
Doug Swartz