On Tue, 19 Jun 2001 03:09:54 +0200 (MEST), Louis Pouzin wrote:

>I want to test and remove one element of an array when it is '-s'.
>
>The following script works, with a diag: Use of uninitialized value, in line 5. It 
>seems related to '-s'.
>
>       #!/usr/local/bin/perl -w
>       @ARGV = (2, '-s', 'fil');
>       my $sel = 0;
>       for (0..$#ARGV) {
>               $ARGV[$_] =~ /^-s$/o || next;
>               $sel = 1; splice(@ARGV,$_,1);
>       }
>       print "$sel, @ARGV \n";
>       __END__
>
>If I replace -s by -\s or -\\s, the diag disappears, but the regex fails. What is a 
>right way to do it ?

The reason is that, when you do that, your @ARGV gets smaller. So you're
testing beyond the end of the array. Plus: you're skipping a file.
You're testing items 0, 1 and 2, but if 1 is dropped, then 2 becomes 1,
and you don't test it.

Some solutions:

 * Do it with a C style for loop (or a while loop), and increment only
if there was no splice.

        for(my $i = 0; $i < @ARGV; ) {
            if($ARGV[$i] eq '-s') {
                splice @ARGV, $i, 1;
            } else {
                $i++;
            }
        }

Very messy, if you ask me.

 * Go backwards through the array.

        for(reverse 0 .. $#ARGV) {
            if($ARGV[$_] eq '-s') {
                splice @ARGV, $_, 1;
            }
        }

Better.

 * But my favourite is to use grep():

        @ARGV = grep { $_ ne '-s' } @ARGV;

Caveat: all untested. How unresponsible. And you have to put the test
for whether '-s' was there, in it somewhere.

-- 
        Bart.

Reply via email to