[REBOL] Re: Translate this code into real Rebol?
From: joel:neely:fedex at: 23-Jan-2002 8:04
Hi, Sunanda,
I can't resist a good refactoring exercise... ;-)
[SunandaDH--aol--com] wrote:
> Here's a useful function (I think). It "pretty prints" numbers
> and currency amounts...
>
...
> It's typical of the sort of code I knock out in a hurry--in this
> case for the prototype I mention in an earlier post...
>
and quite nicely, IMHO!
> It works, but it could almost be Basic. Is there a more Rebolish
> (Rebellious? Rebvolting?) way of doing this?
>
I'm not sure how rebolting I am ;-) but here is a variation that
includes some alternatives you might consider. This one is also
deliberately very simple/explicit, in the interest of readability.
8<----------------------------------------------------------------
pp-number: func [
in-amount [Money! Integer! Decimal!]
/Brackets
/local work out-string thousands-sep decimal-sep currency-sign
][
thousands-sep: ","
decimal-sep: "."
currency-sign: "£"
work: parse/all to-string in-amount decimal-sep
out-string: work/1
if negative? in-amount [remove out-string] ;; remove "-"
if money? in-amount [remove out-string] ;; remove "$"
if 3 < length? out-string [
out-string: skip tail out-string -3 ;; to last 3 digits
while [1 < index? out-string] [ ;; insert as needed
insert out-string thousands-sep
out-string: skip out-string -3
]
]
if 1 < length? work [repend out-string [decimal-sep work/2]]
if money? in-amount [insert out-string currency-sign]
if negative? in-amount [
either Brackets [
out-string: join "(" [out-string ")"]
][
insert out-string "-"
]
]
out-string
]
8<----------------------------------------------------------------
A few comments about strategy:
* I tend to be reductionist in handling things like currency
symbols and negative signs; just eliminate them (remembering
that I did so!) and put them back after solving the simpler
remaining case. The same applied to the fractional part.
* Instead of after-the-fact correction of things like "-," and
"$," I try to keep from occurring at all.
* There are LOTS of variations on inserting thousands separators
in numeric strings. Some are probably more "rebollious" than
the one above, but I think it's fairly clear what it's doing
(and it does use a couple of REBOL-specific string tricks).
* I've gotten more in the habit of reserving RETURN for those
situations where I'm actually doing an "premature exit with
result" from a function. Since REBOL takes the last expression
evaluated in a function as the function's value, ending a
function with RETURN adds time, produces no benefit, and may
help newbie readers avoid learning that standard rule.
However, these are just my opinions, and YMMV.
Thanks for the interesting puzzle!
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;