SPUG: Rebuked...
Ken McGlothlen
mcglk at serv.net
Tue Jan 4 16:30:44 CST 2000
"Steve Laybourn" <otter101 at hotmail.com> writes:
| > sub Cur {
| > my( $ix ) = shift;
|
| ---Let local variable $ix equal the first element of the default array @_,
| which in this case also equals $_. Hmmm, clever, that. How would you handle
| more than one element going in to the array? @_[0], at _[1], etc.?
Well, if you wanted to process each of these in a list, and return a list of
values, you'd write something like:
sub Cur {
my( @ix ) = ();
foreach( @_ ) {
$_ = sprintf( "%.2f", $_ );
1 while s/(.*\d)(\d\d\d)/$1,$2/g;
push( @ix, "\$$_" );
}
return( @ix );
}
Make sense?
| ---This bit puzzles me a little. I understand the rounding function
| represented by the "%.2f" (you described it earlier, I'm looking into that
| further), but wouldn't assigning the result to $ix write over the current
| value of $ix, thusly eliminating the whole dollar part of $ix?
Er, no. The "%.2f" translates something like "29330.5051" to "29330.51"; the
"whole-dollar" part is preserved. For more information on "printf", check out
"man printf" on any Unix system. If you don't have a Unix system handy, let me
know and I'll mail you the page.
| > 1 while $ix =~ s/(.*\d)(\d\d\d)/$1,$2/g;
|
| ---OK, I really had to think this one out, but here goes:
| ---If the regular expression evaluates to true, then do the operation. Hmmm,
| I had wanted to work with up to nine digits and two decimal places, so
| would:
| ---1 while $ix=~ s/(.*\d)(\d\d\d)(\d\d\d)/$1,$2,$3/g;
| ---be more or less correct? The "1 while ..." statement is completely new to
| me. A long time ago I would have thought it to be a label or a line number.
Well, it's a trick. This could also be written
while( $ix =~ s/(.*\d)(\d\d\d)/$1,$2/g ) {
1;
}
The "1" simply returns the value "1" (or true), but doesn't assign it to
anything; it's just a syntactic placeholder that doesn't put too much of a load
on the system. The real work is done by the while statement, which goes until
the match fails. Let's assume that $ix is currently 9872349873.23. This is
what happens.
* The first match becomes:
$1 = 9872349
$2 = 873
Why? Well, the .* is as greedy as possible, and $1 must end with a
digit, so it's going to grab as much as it can. $2 prevents it from
grabbing the remaining three digits. This means that "9872349873.23"
becomes "9872349,873.23".
* The second match becomes:
$1 = 9872
$2 = 349
Why? Well, same thing as before, except that we have to remember that
the comma is not a digit. So this also inserts a comma in the right
place. One more iteration picks up the comma after the 9, and then on
the next iteration, the match fails and the loop ends.
| Again, I apologize for not being terribly good at Perl
Hey, it's not all *that* easy. But there's a lot of power in Perl, and it's
often worth looking around for a more convenient way of doing things rather
than taking the approach you might use in, say, C or FORTRAN. Perl has a very
natural way of working with text and numbers, and there's no better way to
learn than by posting ineffecient code in front of a bunch of amazingly picky
people. :)
| Thanks again. I'll be sure to irritate you again very soon.
No irritation registered. :)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
POST TO: spug-list at pm.org PROBLEMS: owner-spug-list at pm.org
Seattle Perl Users Group (SPUG) Home Page: http://www.halcyon.com/spug/
SUBSCRIBE/UNSUBSCRIBE: Replace ACTION below by subscribe or unsubscribe
Email to majordomo at pm.org: ACTION spug-list your_address
More information about the spug-list
mailing list