A small problem with ScaledDecimal

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

A small problem with ScaledDecimal

larrry
Hi, I had a need to replace the printOn: implementation in ScaledDecimal so that it didn't include the scale.  In other words, I don't want my users to see '3.02s2'.  Being lazy, my first impulse was to remove the code from printOn: that appends the scale, but I realized I'd have to do that every time I upgraded my pharo version.

Instead I tried to implement a subclass called DisplayableScaledDecimal and override printOn.  That seems straightforward and smalltalky, but when I do math on instances of DisplayableScaledDecimal, the results are converted back to ScaledDecimal.  Now I'm looking at re-implementing all the math logic in scaledDecimal to avoid that.

The problem seems to be in the coerce: method, which reads:

coerce: aNumber
"Note: this quick hack could be replaced by double dispatching"
aNumber class = self class ifTrue: [^self class newFromNumber: aNumber scale: (scale max: aNumber scale)].
(aNumber isFraction or: [aNumber isInteger]) ifTrue: [^self class newFromNumber: aNumber scale: scale].
^aNumber

I guess I could override coerce:, but that seems wrong. 

So my question to the smalltalk gods on the list is: Could this be fixed with double dispatching as the comment sort of suggests, and would it be a useful thing to do?


Reply | Threaded
Open this post in threaded view
|

Re: A small problem with ScaledDecimal

drush66
On Tue, Sep 27, 2011 at 1:37 PM, Larry White <[hidden email]> wrote:

> Hi, I had a need to replace the printOn: implementation in ScaledDecimal so
> that it didn't include the scale.  In other words, I don't want my users to
> see '3.02s2'.  Being lazy, my first impulse was to remove the code from
> printOn: that appends the scale, but I realized I'd have to do that every
> time I upgraded my pharo version.
> Instead I tried to implement a subclass called DisplayableScaledDecimal and
> override printOn.  That seems straightforward and smalltalky, but when I do
> math on instances of DisplayableScaledDecimal, the results are converted
> back to ScaledDecimal.  Now I'm looking at re-implementing all the math
> logic in scaledDecimal to avoid that.
> The problem seems to be in the coerce: method, which reads:
> coerce: aNumber
> "Note: this quick hack could be replaced by double dispatching"
> aNumber class = self class ifTrue: [^self class newFromNumber: aNumber
> scale: (scale max: aNumber scale)].
> (aNumber isFraction or: [aNumber isInteger]) ifTrue: [^self class
> newFromNumber: aNumber scale: scale].
> ^aNumber
> I guess I could override coerce:, but that seems wrong.
> So my question to the smalltalk gods on the list is: Could this be fixed
> with double dispatching as the comment sort of suggests, and would it be a
> useful thing to do?

hm not sure about that.

It is usually a good idea that Smalltalk can read object from
representation that is outputed from #printOn: , and loosing a scale
in #printOn: seems to defeat that rule of the thumb.

So maybe avoiding messing with #printOn: is better idea, and
introducing a message of your own that converts to the format you wish
is a better way.

Just my 2c

Davorin Rusevljan
http://www.cloud208.com/

Reply | Threaded
Open this post in threaded view
|

Re: A small problem with ScaledDecimal

larrry


On Tue, Sep 27, 2011 at 7:44 AM, Davorin Rusevljan <[hidden email]> wrote:
On Tue, Sep 27, 2011 at 1:37 PM, Larry White <[hidden email]> wrote:
> Hi, I had a need to replace the printOn: implementation in ScaledDecimal so
> that it didn't include the scale.  In other words, I don't want my users to
> see '3.02s2'.  Being lazy, my first impulse was to remove the code from
> printOn: that appends the scale, but I realized I'd have to do that every
> time I upgraded my pharo version.
> Instead I tried to implement a subclass called DisplayableScaledDecimal and
> override printOn.  That seems straightforward and smalltalky, but when I do
> math on instances of DisplayableScaledDecimal, the results are converted
> back to ScaledDecimal.  Now I'm looking at re-implementing all the math
> logic in scaledDecimal to avoid that.
> The problem seems to be in the coerce: method, which reads:
> coerce: aNumber
> "Note: this quick hack could be replaced by double dispatching"
> aNumber class = self class ifTrue: [^self class newFromNumber: aNumber
> scale: (scale max: aNumber scale)].
> (aNumber isFraction or: [aNumber isInteger]) ifTrue: [^self class
> newFromNumber: aNumber scale: scale].
> ^aNumber
> I guess I could override coerce:, but that seems wrong.
> So my question to the smalltalk gods on the list is: Could this be fixed
> with double dispatching as the comment sort of suggests, and would it be a
> useful thing to do?

hm not sure about that.

It is usually a good idea that Smalltalk can read object from
representation that is outputed from #printOn: , and loosing a scale
in #printOn: seems to defeat that rule of the thumb.

I appreciate the heads-up, but the comment for storeOn: says that storeOn: should be used for storage because printOn: can lose precision.  

I guess maybe I misunderstood the intent here (time to check the blue book) but I thought storeOn: was for machines and printOn: for humans, roughly speaking.  FWIW, I think the rule of thumb that says "programs should be written to be read by human's first and computers second" is violated by having the standard display for a simple decimal number include the scale. 

as an aside: I just watched an old video where Dan Ingalls shows how easy it is to override a numeric type in Smalltalk and just implement the methods that differ.  But that was before ScaledDecimal was around. ;)

But I think you're generally right about this and I was fighting against the language implementation, so I implemented a couple of String constructors that take and format scaled decimals and will scatter them throughout my ui. It's no worse than formatting dates I guess.

thanks.


So maybe avoiding messing with #printOn: is better idea, and
introducing a message of your own that converts to the format you wish
is a better way.

Just my 2c

Davorin Rusevljan
http://www.cloud208.com/