in reply to Proper creation of a negative number

G'day insta.gator,

If you're using Perl v5.14 (or later), you can do all those operations in one statement.

I've chosen transliteration (y///), for the '$' and ',' removal, because it's quicker than substitution (s///); although, you could stick with substitution if you want.

If you do stay with s///, consider the character class '[\$,]' in favour of the alternation '\$|,'. I expect, but don't know for certain, that the former would quicker: Benchmark if you're interested.

Anyway, v5.14 introduced the '\r' modifier which allows you to chain s/// and y/// operations. Here's my test code:

#!/usr/bin/env perl use v5.14; use warnings; my @TFCNTL_Tax; while (<DATA>) { $TFCNTL_Tax[@TFCNTL_Tax] = (split)[8] =~ y/$,//dr =~ s/^(.*)-$/-$1 +/r; } say for @TFCNTL_Tax; __DATA__ 0 0 0 0 0 0 0 0 $1,234.56 0 0 0 0 0 0 0 0 0 $7,890.12- 0 0 0 0 0 0 0 0 0 -$3,456.78 0 0 0 0 0 0 0 0 0 $-9,012.34 0

Output:

1234.56 -7890.12 -3456.78 -9012.34

If you chain two substitutions instead:

$TFCNTL_Tax[@TFCNTL_Tax] = (split)[8] =~ s/[\$,]//gr =~ s/^(.*)-$/ +-$1/r;

the output remains the same.

See also: perlre: Modifiers (for /r); perlop: Quote-Like Operators (for y///); perlop: Regexp Quote-Like Operators (for s///).

-- Ken

Replies are listed 'Best First'.
Re^2: Proper creation of a negative number
by AnomalousMonk (Archbishop) on Jul 09, 2015 at 01:46 UTC
    ... with s///, consider the character class '[\$,]' in favour of the alternation '\$|,'. I expect, but don't know for certain, that the former would quicker ...

    I certainly haven't Benchmark-ed it, but I think that with trie optimization for alternations (introduced with 5.10?), a humble alternation like  a|b|c gets compiled to  [abc] anyway. Even if not, any difference in speed would not, I think, be perceptible unless you were doing a gazillion matches.

    ... the '\r' modifier which allows you to chain s/// and y/// operations.

    I knew about the  /r modifier, but I hadn't really thought about chaining these operations in this way! Come to think of it, such chaining was probably a signficant motive for adding this feature. Granted, the left-associativity of  =~ !~ looks a bit strange in conjunction with the right-assoc. of assignment (the RHS ends up in the middle of the expression), but I can live with that. Again, I've done no Benchmark-ing, but if forced, I think I'd say this trick was more likely to yield speed increases than attention to character class vs. alternation (at least in simple cases).


    Give a man a fish:  <%-(-(-(-<

      You appear to have taken a side-issue and thrust it into the limelight.

      The main focus of my post was about chaining. The opening sentence talked about performing all operations in a single statement. The code was all about chaining. The three documentation links I provided at the end lead to information about chaining.

      And then there were side-issues:

      I pointed out that I had used transliteration, instead of substitution (which the OP's code had), because it was quicker. That was an unequivocal statement.

      [I didn't go into more depth on this issue as it detracted from the chaining operations I was demonstrating. However, it is documented in "perlperf - Perl Performance and Optimization Techniques" (specifically under "Search and replace or tr").]

      I then went on to say that, if the OP chose not to use transliteration, then a character class might be quicker than alternation. I said "I expect" and "don't know for certain"; and went on to suggest benchmarking. There was no unequivocal statement here.

      -- Ken