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

I've also tried -2 and -3.
use Text::CSV; my $csv_tie = Text::CSV->new({binary=>1}) or die "CSV doesn't work: ". +Text::CSV->error_diag(); my $csv_file = "some_file.csv"; if(open my $H_csv_file, "<", $csv_file){ while(my $row = $csv_tie->getline($H_csv_file)){ printf "(%s)\n", join(';', @$row[0..-1]); #I tried also @{$row +}[0..-1] } close($H_csv_file); }else{ print STDERR "Can't open CSV csv: $csv_file\n"; }
Prints emtpy results for each record in csv file:

() () () () ()

, but, if I use some positive index number, like 0..7, for example, it works fine:

(1094;СР600;7;28;42722;International;84abcdefgh0;Molokov) (1095;СР200;7;28;42722;International;84abcdefgh5;Babin) (1096;СР200;7;28;42722;International;84abcdefgh9;Rechkunova)

I've read in perl documentation about slices, it gives examples with negative numbers, so it should work?, I would suppose.
  • Comment on Slicing an array variable with a -1 or any negative number doesn't work
  • Download Code

Replies are listed 'Best First'.
Re: Slicing an array variable with a -1 or any negative number doesn't work
by Eily (Monsignor) on Nov 29, 2017 at 11:16 UTC

    Slicing with negative numbers does work. What doesn't however is 0..-1, as the .. operator only counts up. So (0..-1) is an empty list.

    @{$row}[0,-1] will work. Or if you want a list of negative number, you can make one with map: @{$row}[map -$_, 0..2]

    Edit: oh I thought you wanted 0..-2 to mean (0, -1, -2), but maybe hippo's interpretation is what you wanted: from the first element to the one before the last. In which case you have to use $#{$row}, the index of the last element as proposed by hippo

      Ok, I got it.
      -1 or other -x (negative numbers) in slices, can only work with commas, but not with ..
      I see.

      Thank You.

        -1 or other -x (negative numbers) in slices, can only work with commas, but not with ..

        Nope. The point is that ".." counts up. These work:

        @letters = ('a'..'z'); say for @letters[-5..-1]; say for @letters[reverse(-1..0)];
        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: Slicing an array variable with a -1 or any negative number doesn't work
by hippo (Archbishop) on Nov 29, 2017 at 11:16 UTC

    Since -1 is less than zero the range operator [0..-1] doesn't give anything. You'll have to extract the value yourself. eg: @$row[0..$#$row]

      FWIW, slicing in Python works the way the OP seems to expect. One of the few times where Perl makes more sense than Python IMO.

        Then you'll be disappointed to learn about substr($s, 0, -1) and slice(@a, 0, -1)

Re: Slicing an array variable with a -1 or any negative number doesn't work
by ikegami (Patriarch) on Nov 29, 2017 at 18:36 UTC

    The syntax for an array slice is @NAME[LIST], not @NAME[NUM..NUM]. What that means is that .. is just an ordinary range operator in this scenario.

    The range operator (in list context) returns an ascending sequence of numbers starting with its LHS operand and ending with its RHS operand. For example, 0..3 produces the foud scalars 0, 1, 2 and 3, while 0..-1 doesn't produce anything.

    Replace

    @$row[0..-1]

    with

    @$row[0..@$row-1]

    or

    @$row[0..$#$row]

    or just

    @$row