NAME

Perl::Critic::Policy::References::RequireSlices - Use array and hash slices for multiple lookups

DESCRIPTION

Value slices of arrays and hashes, and key-value slices of hashes, permit selecting multiple indexes/keys/values in a single call. This reduces redundancy of code and permits runtime optimization.

$array[1], $array[3]                 # no
@array[1,3]                          # yes

$hash{one}, $hash{two}               # no
@hash{qw/one two/}                   # yes

$hash{$one}, $hash{$two}             # no
@hash{$one, $two}                    # yes

$hash{one}, $hash{two}, $hash{three} # no
@hash{qw/one two three/}             # yes

$hash{one}{two}, $hash{two}{one}     # yes
$hash{one}{one}, $hash{one}{two}     # no
@{$hash{one}}{qw/one two/}           # yes

CONFIGURATION

By default, two lookups of the same object in a sequence is considered a violation. In living code, it may be easier to manage rewriting to slices when hitting three lookups. This can be controlled with the minimum option:

[ValuesAndExpressions::RequireSlices]
minimum = 3

This setting represents the number of symbol uses and not the number of elements being selected. In particular, there is no detection of the count of keys inside existing slices:

@hash{qw/one two/}, $hash{three}  # okay with minimum=3

NOTES

A violation occurs for array subscripts and hash key 'subscripts' at any level. Violations are attached only to the first occurrence in the list. A list may still have multiple violations, however, such as with:

$hash{one}, $hash{two}, 5, $hash{three}, $hash{four} # no
@hash{qw/one two/}, 5, @hash{qw/three four/}         # yes

Written code optimization

Slices are useful when more than one subscript is needed, but the actual code savings is dependent on: V the length of the variable name; N the number of keys referenced; K the total length of the N keynames;

If a hash is used in a literal value-slicing situation:

$hash{one}, $hash{two} takes (N+N*V+2(N-1)+2N+K)
@hash{qw/one two/}     takes (1+V+2+4+K+(N-1))

The first is (sigils, variable name redundancy, comma-spaces, curlies, keys). The second is (sigil, variable name, curlies, qw, keys, and the spaces between). Totals are K+4N+NV-2 vs K+N+V+6, so the rewrite reduces space when V+8<N(V+4).

Hash used with variable value-slicing:

$hash{$one}, $hash{$two} takes (N+N*V+2(N-1)+2N+K)
@hash{$one,$two}         takes (1+V+2+K+2(N-1))

Totals are K+4N+NV-2 vs K+2N+V+1, so the rewrite reduces space when V+3<N(V+3).

Hash used with literals quoted separately:

$hash{one}, $hash{two} takes (N+N*V+2(N-1)+2N+K)
@hash{'one', 'two'}    takes (1+V+2+2N+K+2(N-1))

Totals are K+4N+NV-2 vs K+4N+V+1, so the rewrite reduces space when V+3<N(V+1).

Hash reference with literal postfix dereferencing:

$href->{one}, $href->{two} takes (5N+NV+2(N-1)+K)
@$href{qw/one two/}        takes (2+V+2+4+K+(N-1))

Rewrite reduces space when V+9<N(V+6)

Hash reference with literal postfix dereferencing, and postfix slicing:

$href->{one}, $href->{two} takes (5N+NV+2(N-1)+K)
$href->@{qw/one two/}      takes (4+V+2+4+K+(N-1))

Rewrite reduces space when V+11<N(V+6)

For V>0, the right-hand sides increase with N, and the LHS are fixed. For N>=2, N(V+k)>=2V+2k=V+(2k+V)>=V+(2k+1). All of the above inequalities hold, except the separately-quoted case which may be equal in some cases.

BUGS

Key-value slicing is not currently supported.

Perl version is not considered.

Messaging could be a bit more specific.

SEE ALSO

Perl::Critic::Policy::ValuesAndExpressions::ProhibitSingleArgArraySlice