sub big_money {
my $number = sprintf "%.2f", shift @_;
# Add one comma each time through the do-nothing loop
1 while $number =~ s/^(-?\d+)(\d\d\d)/$1,$2/;
# Put the dollar sign in the right place
$number =~ s/^(-?)/$1\$/;
$number;
}
This subroutine uses some techniques you haven't seen yet, but
they logically follow from what we've shown you. The first line
of the subroutine formats the first (and only) parameter to have
exactly two digits after the decimal point. That is, if the parameter
were the number 12345678.9, now our
$number is the string
"12345678.90".
What does that say to do? It says that, as long as the substitution
returns a true value (signifying success), the loop body should run.
But the loop body does nothing! That's okay with Perl, but it
tells us that the purpose of that statement is to do the conditional
expression (the substitution), rather than the useless loop body. The
value 1 is traditionally used as this kind of a
placeholder, although any other value would be equally
useful.[338] This
works just as well as the loop above:
'keep looping' while $number =~ s/^(-?\d+)(\d\d\d)/$1,$2/;
So, now we know that the substitution is the real purpose of the
loop. But what is the substitution doing? Remember that
$number will be some string like
"12345678.90" at this point. The pattern will
match the first part of the string, but it can't get past the
decimal point. (Do you see why it can't?) Memory
$1 will get "12345", and
$2 will get "678", so the
substitution will make $number into
"12345,678.90" (remember, it couldn't match
the decimal point, so the last part of the string is left untouched).
Do you see what the dash is doing near the start of that pattern?
(Hint: The dash is allowed at only one place in the string.)
We'll tell you at the end of this section, in case you
haven't figured it out.
We're not done with that substitution statement yet. Since the
substitution succeeded, the do-nothing loop goes back to try again.
This time, the pattern can't match anything from the comma
onward, so $number becomes
"12,345,678.90". The substitution thus adds a
comma to the number each time through the loop.
Speaking of the loop, it's still not done. Since the previous
substitution was a success, we're back around the loop to try
again. But this time, the pattern can't match at all, since it
has to match at least four digits at the start of the string, so now
that is the end of the loop.