On Tue, 19 Jun 2001 15:25:56 +0200, Bart Lateur wrote:
>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.
Does this mean that the "for" boundaries are evaluated only on the 1st loop ? Then
$#ARGV doesn't reflect the array variations.
>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.
That's right.
>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.
It works, with the addition of $sel=1 after splice.
> * Go backwards through the array.
> for(reverse 0 .. $#ARGV) {
> if($ARGV[$_] eq '-s') {
> splice @ARGV, $_, 1;
> }
> }
>Better.
It works. Same addition as above.
> * 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.
It's great. Here is the complete script:
#!/usr/local/bin/perl -w
@ARGV = (2,'-s','fil'); my $sel = 0;
grep { /^-s$/o && ($sel = 1) } @ARGV;
@ARGV = grep { $_ ne '-s' } @ARGV;
print "$sel, @ARGV \n";
__END__
Could the 2 grep's be somehow merged ?
Thanks Bart. You taught me new tricks. I'm still in the lower learning curve.
=====