[squeak-dev] Really strange problem
Levente Uzonyi
leves at elte.hu
Tue Jan 18 13:21:27 UTC 2011
On Tue, 18 Jan 2011, Casimiro de Almeida Barreto wrote:
> Hello,
>
> I'm writing an example (a message for calculating combinations out of a
> collection and I found an amazing error. When line combOfRest :=
> workList combinations: (n - 1) is called VM tries to evaluate things in
> the self context (as if workList was self) and then x is nil and that
> causes an error. Is this behavior expected?
Which VM and image do you use? (I couldn't reproduce this problem.)
But I found a bug in your code. This line:
(combOfRest at: j) add: x before: 1 ].
should probably be:
(combOfRest at: j) addFirst: x ].
And there's another bug(?) which causes your method to sometimes return a
hierarchical structure instead of simply a collection of collections. But
you shouldn't bother with it, because this method can be implemented much
easier:
SequenceableCollection >> combinations: n
^Array streamContents: [ :stream |
self combinations: n atATimeDo: [ :each |
stream nextPut: each copy ] ]
Levente
>
> I was expecting that workList combinations: x would be executed in a new
> context (since it's an instance of IntegerArray)
>
> By the way, when I inspect I discover that there are 3 instances of x
> (one with right value, and two nil).
>
> CdAB
>
> IntegerArray>>combinations: n
> "This message returns all possible combinations of n elements
> from self"
>
> | theCombinations workList |
>
> "First let's check conditions"
> n class ~= SmallInteger ifTrue: [ self error: 'argument should
> be SmallInteger but is: ',n class asString ].
> (n < 1 or: [ n > self size ]) ifTrue: [ self error: 'argument
> out of range: ',n asString ].
>
> theCombinations := OrderedCollection new.
>
> "Basic case #1: size equals to data size"
> n = self size ifTrue: [
> | x |
> x := OrderedCollection newFrom: self.
> theCombinations add: x.
> ^theCombinations ].
>
> "Basic case #2: size equals to 1"
> n = 1 ifTrue: [
> 1 to: self size do: [ :i |
> | x |
> x := OrderedCollection with: (self at: i).
> theCombinations add: x ].
> ^theCombinations ].
>
> workList := self class newFrom: self.
>
> "Generic case"
> 1 to: self size - n + 1 do: [ :i |
> | x combOfRest |
>
> x := workList at: 1.
>
> workList := workList allButFirst.
>
> *combOfRest := workList combinations: (n - 1)*.
>
> 1 to: combOfRest size do: [ :j |
> (combOfRest at: j) add: x before: 1 ].
>
> theCombinations add: combOfRest ].
>
> ^theCombinations
>
>
>
>
>
>
>
More information about the Squeak-dev
mailing list
|