SPUG: Rebuked...

Scott Blachowicz sab at rresearch.com
Tue Jan 4 13:42:55 CST 2000

On Tue, Jan 04, 2000 at 11:09:20AM -0800, Steve Laybourn wrote:
> >So here's my rewrite of your function:
> (My turn to see if I have the interpretation of this correct):
> >
> >	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 

It does? I'm not sure that's true (that '$_' is set to the first
element of the '@_' arg list to the function).

> more than one element going in to the array? @_[0], at _[1], etc.?

	my ($ix1, $ix2, $ix3) = @_;
	my $ix1 = shift;
	my $ix2 = shift;
	my $ix3 = shift;

Each of those 'shift's returns & removes the first element from the
array (@_ is the default array for shift).

> >	    $ix = sprintf( "%.2f", $ix );
> ---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?

It's using a standard C printf() style format string.  Check it's
documentation.  Basically that specification would use as much space
as neeeded for the whole dollar part and only 2 digits for the
fractional part.

> >	    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.

The '1' is just a statement to be able to use with the 'while' loop.  It
doesn't do a whole lot because the beef is in the conditional:


The CONDITION is a 'substitute' command.  If the substitute command
did something it'll return a "true" value for the CONDITION, which
will cause it to be executed again.  So, it repeatedly looks for
occurrences of 4 digits in a row, inserting a comma before the last 3
digits in that run.  So, it'll work for any length number.  Your
suggested revision will only work for to insert commas in runs of 7 or
more digits.

That while loop could've been formulated like this [untested snippet] as well:

	$ix = "$1,$2$3"
		while ($ix =~ m/^(.*\d)(\d\d\d)($|\D.*)$/);

if you want the statement to actually do something.  But the original
suggestion is a bit more concise :-).

Scott.Blachowicz at seaslug.org

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    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