in reply to doing tr/// on-the-fly?

First off, tr/// does not do interpolation, strings or regular expressions.    For that you need s///g.

Your expression my $result = eval "tr/$search/$replace/"; is short for my $result = eval "\$_ =~ tr/$search/$replace/"; but it appears that there is nothing in $_.    Perhaps you meant:

my $s = 'eabcde'; my $search = 'abcd'; my $replace = 'efgh'; eval "\$s =~ tr/$search/$replace/"; print "$search\n"; print "$replace\n"; print "$s\n";

Replies are listed 'Best First'.
Re^2: doing tr/// on-the-fly?
by toolic (Bishop) on Mar 18, 2010 at 01:27 UTC
    Extending this to get the number of substitutions...
    my $result; eval "\$result = \$s =~ tr/$search/$replace/";
    Also, the OP would have gotten warning messages with use warnings;

      Thanks. That is useful information to have.

      Any information on CPAN modules to use for escaping? It would really help if something were installed by default. :)

        Dynamic tr is kind of nonsensical, just use s///, it will be just as fast
Re^2: doing tr/// on-the-fly?
by Anonymous Monk on Mar 18, 2010 at 01:26 UTC

    Thanks. That helps some.

    Changing the code to the following:

    #!/usr/bin/env perl use strict; my $s = 'eabcde'; my $t = $s; print "$t\n"; $t =~ tr/abcd/efgh/; print "$t\n"; print '*' x 4, $/; my $search = 'abcd'; my $replace = 'efgh'; $t = $s; print "$t\n"; eval { $t =~ tr/$search/$replace/; }; print "$search\n"; print "$replace\n"; print "$t\n";
    Gives me the results:
    eabcde eefghe **** eabcde abcd efgh epbade
    I don't see why the results of tr/// differ.
      eval BLOCK and eval EXPR, despite the similarity in name, are very different functions. You might know the former as try, an exception catching block. The latter also catches exceptions, but its goal is to parse and run dynamically generated Perl code.
      Okay, I didn't duplicate exactly what you said. The following code:
      #!/usr/bin/env perl use strict; my $s = 'eabcde'; my $t = $s; print "$t\n"; $t =~ tr/abcd/efgh/; print "$t\n"; print '*' x 4, $/; my $search = 'abcd'; my $replace = 'efgh'; $t = $s; print "$t\n"; eval "\$t =~ tr/$search/$replace/"; print "$search\n"; print "$replace\n"; print "$t\n";
      ...does give me the expected results:
      eabcde eefghe **** eabcde abcd efgh eefghe
      Why the difference?

        Because:

        eval { $t =~ tr/$search/$replace/; };

        is just normal perl code where there is no interpolation so '$' is replaced with '$' and 's' is replaced with 'r' and 'e' is replaced with 'e' and 'a' is replaced with 'p', etc. while using string eval interpolates the variables $search and $replace.