So I was playing with Squeak 3.9, walking through the stuff in Squeak
By Example (which is terrific, by the way). Turns out StringTest>>#testIndexOf is failing, because it asserts that 'abc-' asWideString indexOfAnyOf: (CharacterSet newFrom: ' -0123456789') should be 4, and instead it's 0. Well, String>>#findFirstInString:inSet:startingAt: works by iterating over the string to find either an object in the set or the end of the string (literally, there are two tests in the whileTrue: condition) and then checking after the end of the loop to see if the loop counter got to the last character. Well, that approach is not going to work; it can't tell whether it got to the last character and then found that it was in the set, or instead it never found a character in the set. It's a little weird to have an obvious bug like that in a relatively fundamental method like that (is it some kind of prank?) but anyway, I fixed it (rather suboptimally) in the attached changeset, and now I get an error later on in StringTest>>#testIndexOf, namely that I can't make a CharacterSet newFrom: (String with: 811 asCharacter with: 812 asCharacter) because the CharacterSet's map is a 256-element ByteArray, and there ain't no position 812 in a 256-element ByteArray! Also, it's a little weird that the code is full of underscores rather than :='s, as if it hadn't been touched in five years or more, but the version browser (is that the right word?) says that it was modified in 4/10/2005, and shows no versions older than that. So what's going on? How did I end up running code that fails basic unit tests due to bugs that are obvious even to me? I don't know Smalltalk, so I think the obviousness of the bug owes more to the excellent debugging facilities and the nature of the bug than to my own abilities. I compiled the Squeak 3.9 virtual machine from sources according to Ian Piumarta's "instructions for the impatient" in README, on my fairly standard Debian Etch machine, and I'm running the Squeak3.9-final-7067.image from the Squeak web site. My machine has occasionally proven unreliable in the past (crashing kernel compiles and the like); could that somehow be related? Did some bit-flip send me into the Museum of Discarded Code That Never Worked? 'From Squeak3.9 of 7 November 2006 [latest update: #7067] on 15 December 2007 at 9:47:48 pm'! !String class methodsFor: 'primitives' stamp: 'kjs 12/15/2007 21:26'! findFirstInString: aString inSet: inclusionMap startingAt: start "Trivial, non-primitive version" | i stringSize ascii more | inclusionMap size ~= 256 ifTrue: [^ 0]. stringSize _ aString size. more _ true. i _ start - 1. [more and: [i + 1 <= stringSize]] whileTrue: [ i _ i + 1. ascii _ (aString at: i) asciiValue. more _ ascii < 256 ifTrue: [(inclusionMap at: ascii + 1) = 0] ifFalse: [true]. more ifFalse: [ ^ i ]. ]. ^ 0. ! ! |
Yes, this is a bug, a known one: http://bugs.squeak.org/view.php?id=3574
It has been corrected in 3.10. Squeak had a process of evolution with a lot of additions, some breaking methods that originally worked. Now, community is in a process of writing SUnit TestCase and tracking such bugs and regression. 3.9 did a large step toward that direction, 3.10 also, but squeak library is huge! If you want to help, you are welcome, open a mantis account and fill bug reports, we will be grateful for that. As for underscore, they once were left arrows before squeak switched to fonts and encodings from the external world. Don't know why not all code translated yet. Cheers Nicolas Kragen Javier Sitaker a écrit : > So I was playing with Squeak 3.9, walking through the stuff in Squeak > By Example (which is terrific, by the way). Turns out > StringTest>>#testIndexOf is failing, because it asserts that 'abc-' > asWideString indexOfAnyOf: (CharacterSet newFrom: ' -0123456789') > should be 4, and instead it's 0. > > Well, String>>#findFirstInString:inSet:startingAt: works by iterating > over the string to find either an object in the set or the end of the > string (literally, there are two tests in the whileTrue: condition) > and then checking after the end of the loop to see if the loop counter > got to the last character. Well, that approach is not going to work; > it can't tell whether it got to the last character and then found that > it was in the set, or instead it never found a character in the set. > > It's a little weird to have an obvious bug like that in a relatively > fundamental method like that (is it some kind of prank?) but anyway, I > fixed it (rather suboptimally) in the attached changeset, and now I > get an error later on in StringTest>>#testIndexOf, namely that I can't > make a CharacterSet newFrom: (String with: 811 asCharacter with: 812 > asCharacter) because the CharacterSet's map is a 256-element > ByteArray, and there ain't no position 812 in a 256-element ByteArray! > > Also, it's a little weird that the code is full of underscores rather > than :='s, as if it hadn't been touched in five years or more, but the > version browser (is that the right word?) says that it was modified in > 4/10/2005, and shows no versions older than that. > > So what's going on? How did I end up running code that fails basic > unit tests due to bugs that are obvious even to me? I don't know > Smalltalk, so I think the obviousness of the bug owes more to the > excellent debugging facilities and the nature of the bug than to my > own abilities. > > I compiled the Squeak 3.9 virtual machine from sources according to > Ian Piumarta's "instructions for the impatient" in README, on my > fairly standard Debian Etch machine, and I'm running the > Squeak3.9-final-7067.image from the Squeak web site. > > My machine has occasionally proven unreliable in the past (crashing > kernel compiles and the like); could that somehow be related? Did > some bit-flip send me into the Museum of Discarded Code That Never > Worked? > > 'From Squeak3.9 of 7 November 2006 [latest update: #7067] on 15 December 2007 at 9:47:48 pm'! > > !String class methodsFor: 'primitives' stamp: 'kjs 12/15/2007 21:26'! > findFirstInString: aString inSet: inclusionMap startingAt: start > "Trivial, non-primitive version" > | i stringSize ascii more | > inclusionMap size ~= 256 ifTrue: [^ 0]. > stringSize _ aString size. > more _ true. > i _ start - 1. > [more and: [i + 1 <= stringSize]] whileTrue: [ > i _ i + 1. > ascii _ (aString at: i) asciiValue. > more _ ascii < 256 ifTrue: [(inclusionMap at: ascii + 1) = 0] ifFalse: [true]. > more ifFalse: [ ^ i ]. > ]. > ^ 0. > ! ! > > > |
Free forum by Nabble | Edit this page |