Bug Involving Modified #to:by:do:

R. A. Harmon harmonra at webname.com
Sun Jan 31 00:11:50 UTC 1999


At 09:08 AM 1/30/99 -0600, Tim Olson wrote:
>Richard Harmon wrote:
>
>>I modified Number 'intervals' #to:by:do: method by adding at the beginning:
>>
>>	step = 0 ifTrue: [
>>		^self error: 'step must be non-zero.'
>>	].
>>
>>
>>then evaluated:
>>
>>	5 to: 1 by: 0 do: [ :n | ^#bogus].
>>
>>it returns bogus.
>
>
>Ralph Johnson replied:
>
>>Traditionally to:do: is optimized by the compiler when you send
>>it to a number, so the to:do: method is never called.  I bet that
>>Squeak does the same thing with to:by:do:.  The problem is that
>>you are catching the compiler cheating.
>
>
>Yep; there is a hint in the beginning of the method that Richard modified 
>that states this.  Richard, the compiler macro-expansions (inlined code) 
>are in the MessageNode class (macro transformations category).  If you 
>want to continue to play with this, here is a change to the to:by:do 
>transformation that causes it to not in-line if the step amount is zero.
[change snipped]

[embarrassment mode on]
I even dutifully incorporated said hint into to my own comments!  Thanks for
the delicate way you pointed it out.  I sometimes get so busy chopping off
branches, I don't notice I'm sitting on the one I'm chopping off.  What are
you going to do with a guy like that?  You give him Squeak, comment
pitfalls, and he eats the floppy disk!
[embarrassment mode off]


Thanks for the change.  It worked like a champ.  I wanted to modify
#to:by:do: for ANSI to signal an exception if step is zero.

I also need to change "something" to handle my implementation of
ScaledDecimal step or by parameters.  The following snippet shows an example
of the odd results currently produced:

        | x | x := OrderedCollection new.
        (1/2) to: 5.5s2 by: 2.0 do: [ :n | x add: n]. ^x asArray
                "-> ((1/2) + 2.5 4.5 )"

The Interval elements should all be Float as the default conversion of
Fraction operation Float is Float.

I didn't spot anything obvious.  Is that "something" going to get REAL
complicated or is there a relatively simple fix?



Is there some reason that nextValue should be set before checking for the
error?  Will I step on something if I swap it and check for the error before
setting nextValue?

!Number methodsFor: 'intervals' stamp: 'tao 1/30/1999 08:58'!
to: stop by: step do: aBlock 
	"Normally compiled in-line, and therefore not overridable.
	Evaluate aBlock for each element of the interval (self to: stop by: 
step)."
	| nextValue |
	nextValue _ self.
	step = 0 ifTrue: [self error: 'step must be non-zero'].


I do appreciate the help folks.

--
Richard A. Harmon          "The only good zombie is a dead zombie"
harmonra at webname.com           E. G. McCarthy





More information about the Squeak-dev mailing list