On Thu, 28 Feb 2002 19:15:16 -0500, Joshua Juran wrote:

>If you wrote this as a reuseable subroutine, $origpath and $destpath would
>vary between invocations.

Yes. But only $origpath matters.

>To avoid the performance hit of recompiling the
>regex each time, you could use eval like this:
>
>my $orig2dest = eval {
>       sub {
>               my ($file) = @_;
>               (my $dest = $file) =~ s/^\Q$origpath/$destpath/;
>               return $dest;
>       }
>};

Wrong eval()  here! This *does *not* recompile the sub when you're 
creating a new sub! For that, you need eval STRING!

A few remarks:

 * a closure would be a neat idea here. For that, you create a sub with
$origpath and $destpath as parameters, and which returns a sub -- this
sub.

 * For older Perls, such as the old MacPerl, the /o option is useful.

 * Unfortunately, with these older perls, /o and closures don't work
well together.

 * So, for these older perls, you need an eval string in the closure
producing sub.

 * For newer perls, such as the brandnew MacPerl, Niether the /o option
nor the eval are really necessary. Regexes based on a variable will only
recompile the regex if the variable has changed between invocations.

So, for the sake of old MacPerls:

        sub genconversion {
            my($origpath, $destpath) = @_;
            return eval <<'-END-';
               sub {
                  my ($file) = @_;
                  $file =~ s/^\Q$origpath/$destpath/o;
                  return $file;
               }
        -END-
        }

        $orig2dest = genconversion('/foo', '/bar');

It should work on newer perls too, although it's a bit of overkill to do
it this way.

>Then, replace the substitution line in the original code with:
>
>my $dest = $orig2dest->($file);

You got that right.

-- 
        Bart.

Reply via email to