Login
RT #74429: 'Negative array index should be used' a little misleading
authorTom Wyant <harryfmudd@comcast.net>
Tue, 28 Feb 2012 02:53:09 +0000 (02:53 +0000)
committerTom Wyant <harryfmudd@comcast.net>
Tue, 28 Feb 2012 02:53:09 +0000 (02:53 +0000)
The problem was that the documentation of
Variables::RequireNegativeIndices did not mention at all the fact
the semantics of $#foo-$n change when $n becomes greater than $#foo,
whereas the semantics of -$n do not. The author of the ticket seems to
have been burned when trying to straighten out non-compliances.

The long explanation of a non-compliance has been revised to feature the
semantics change prominently.

The short explanation has not been changed, because I confess my
inability to do significantly better without taking significantly more
verbage.

lib/Perl/Critic/Policy/Variables/RequireNegativeIndices.pm

index d065f49..0530175 100644 (file)
@@ -202,30 +202,26 @@ distribution.
 
 =head1 DESCRIPTION
 
-Conway points out that
+Perl treats a negative array subscript as an offset from the end. Given
+this, the preferred way to get the last element is C<$x[-1]>, not
+C<$x[$#x]> or C<$x[@x-1]>, and the preferred way to get the next-to-last
+is C<$x[-2]>, not C<$x[$#x-1> or C<$x[@x-2]>.
 
-    $arr[$#arr];
-    $arr[$#arr-1];
-    $arr[@arr-1];
-    $arr[@arr-2];
+The biggest argument against the non-preferred forms is that B<their
+semantics change> when the computed index becomes negative. If C<@x>
+contains at least two elements, C<$x[$#x-1]> and C<$x[@x-2]> are
+equivalent to C<$x[-2]>. But if it contains a single element,
+C<$x[$#x-1]> and C<$x[@x-2]> are both equivalent to C<$x[-1]>. Simply
+put, the preferred form is more likely to do what you actually want.
 
-are equivalent to
-
-    $arr[-1];
-    $arr[-2];
-    $arr[-1];
-    $arr[-2];
-
-and the latter are more readable, performant and maintainable.  The
-latter is because the programmer no longer needs to keep two variable
-names matched.
+As Conway points out, the preferred forms also perform better, are more
+readable, and are easier to maintain.
 
 This policy notices all of the simple forms of the above problem, but
 does not recognize any of these more complex examples:
 
     $some->[$data_structure]->[$#{$some->[$data_structure]} -1];
-    my $ref = \@arr;
-    $ref->[$#arr];
+    my $ref = \@arr; $ref->[$#arr];
 
 
 =head1 CONFIGURATION