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

Please help this lost soul,

It is often quite useful to change text in multiple files at the same time. Although there is a one-liner for changing all files in current directory, i wanted to include or exclude files based on pattern matches (like /html/); even on multiple pattern matches (say /html/ and /cgi/) across multiple directories.

Then a problem arose. In trying to use pattern matches i came up with this:

# $temp was already defined, i just initialize its value here 1: my (@temp, $in, $out); $temp = ''; 2: 3: PROCESS: while ($temp = shift @files) { 4: $temp = $dir.'/'.$temp; 5: 6: (-f $temp)?(push @temp, $temp):(next PROCESS); 7: IN: foreach $in (@include) { 8: last IN if ($temp =~ eval $in); 9: pop @temp if ($in eq $include[$#include]); 10: } 11: OUT: foreach $out (@exclude) { 12: next OUT if ($temp !~ eval $out); 13: (pop @temp and last OUT) if ($temp =~ eval $out); 14: } 15:} 16:@files = @temp;

This code pops off every value! In other words the eval $out (line 13 above) always returns true (at least in my testing). Whenever i ran it there would be no files left in @temp or @files at the end of the while loop. The logic should be correct (albeit i'm not sure on this point) and there don't seem to be any glaring errors from my point of view. Please help.

jynx

ps: example of use:
perl changeText --include /html/ --exclude /shtml/ s/ome/pattern/g
(Assume default directory is `.')

Replies are listed 'Best First'.
Re: Including and Excluding with Impunity
by chromatic (Archbishop) on Nov 13, 2000 at 09:37 UTC
    Why not use grep against the contents of an array to include or to exclude as you see fit?
    foreach my $include (grep(!/\.html$/, @files)) { # do something }
RE: Including and Excluding with Impunity
by mwp (Hermit) on Nov 13, 2000 at 06:27 UTC

    Try this:

    ... if(eval "\$temp =~ $out");

    I'm not entirely sure what's happenening when you attempt to use eval like you are, but it's definitely not what you want. You might be better off passing the inc/exc directories as strings instead of RegExp pieces, then you can do =~ /$out/ instead of using eval.

    Otherwise, I recommend that you play around with File::Find. You would be able to accomplish your goals a little easier than attempting to parse the directory tree by yourself.

    Good luck,

    Alakaboo

Re: Including and Excluding with Impunity
by snax (Hermit) on Nov 13, 2000 at 21:17 UTC
    alakaboo is right. In your code,
    $temp =~ eval $out
    is just checking to see if $_ matches the "regex" in $out, which yields a null string if it doesn't, to which you then apply the binding operator with $temp, which simply succeeds -- dunno why, but it does. Thus your test is true every time or false every time depending on how $_ matches up with the $out regex. If it matches, it is false (binding to an integer 1 fails); if it doesn't match, it is true (binding to a null string succeeds).


      That makes sense i suppose. The problem i have is that the
      $temp =~ eval $in
      does work. i ran through with perl debugger and the includes matched when they should and didn't when they shouldn't. This was what had me baffled most...

      i'll retry it using grep, thanx all for your help.

      jynx