kri54sub has asked for the wisdom of the Perl Monks concerning the following question:

newbie question:

How do I use variable interpolation within a range operator?

eg: <THIS WORKS>

while (<FH>) { print if ( (/Btree/../PSE:/) or (m#PROCESSING ../Btree.gz#) or (m#PROCESSING ../log.dummy-10-05-18-05.gz#) or (m#PROCESSING ../log.dummy-10-01-06-05.gz#) ) } ----------------------------------------------------
Instead of the above relative hard coded path, I want to use a variable which can be interpolated within this range operator, as in
@ARGV = qw#../log.dummy-10-01-06-05.gz ../log.dummy-10-05-18-05.gz ../ +Btree.gz/#; foreach $input (@ARGV) { open (FH,"zcat $filename|") or die "Can't Open file: $!\n"; while (<FH>) { print if ( (/Btree/../PSE:/) or (m#PROCESSING ../$input#) ) } }
But this doesn't work. Any suggestion on this interpolation. I tried the `$input` as well.

Replies are listed 'Best First'.
Re: variable interpolation within a range operator
by kyle (Abbot) on Feb 26, 2008 at 03:25 UTC

    You're interpolating $input with a value such as '../log.dummy-10-01-06-05.gz' into the pattern m#PROCESSING ../$input#. After the interpolation, that's m#PROCESSING ../../log.dummy-10-01-06-05.gz#. That's different from the working pattern you had before (m#PROCESSING ../log.dummy-10-01-06-05.gz#).

    One thing you'll want to do, since you're matching literal strings, is to use quotemeta or \Q in the pattern. As it is, when you interpolate $input, the initial dots in '../log.dummy-10-01-06-05.gz' could match any character (as they normally would in a regexp).

    In short, I think you want this:

    m#PROCESSING \Q$input#

    If I may make a few more suggestions...

    • Please don't use # as delimiters. It really plays havoc with my context-sensitive editor. I personally like m{}.
    • Since you're looking for literal strings, index would be faster (but maybe harder to read).
    • Use three argument open: open my $zcat_fh, '-|', "zcat $filename" or die ...
    • Have a look at Writeup Formatting Tips. Specifically, you need <code> tags around your code to make it look right.
    • If you don't already, use strict and warnings.
      Thank you for quotemeta and the suggestions especially the 3 argument open command. I do use strict and warning. For posting purposes I just took only a snippet of my code. Thanks again for the help.
Re: variable interpolation within a range operator
by jwkrahn (Abbot) on Feb 26, 2008 at 04:40 UTC

    You could do it like this:

    @ARGV = map "zcat $_ |", qw[ ../log.dummy-10-01-06-05.gz ../log.dummy-10-05-18-05.gz ../Btree.gz/ ]; while ( <> ) { print if /Btree/ .. /PSE:/ or /PROCESSING \Q$ARGV/; }