close
Skip to content

Add new Style/WithIndexOffset cop#14993

Open
justindell wants to merge 1 commit into
rubocop:masterfrom
justindell:add-style-with-index-offset
Open

Add new Style/WithIndexOffset cop#14993
justindell wants to merge 1 commit into
rubocop:masterfrom
justindell:add-style-with-index-offset

Conversation

@justindell
Copy link
Copy Markdown

Summary

Adds a new Style/WithIndexOffset cop that detects offset arithmetic on the index variable inside each_with_index or with_index blocks.

When every usage of the index variable in a block applies the same constant offset (e.g. index + 1), the offset can be passed directly to with_index instead.

Before

array.each_with_index do |item, index|
  puts index + 1
end

array.each.with_index do |item, index|
  puts index + 1
end

array.each_with_index do |item, index|
  puts index.succ
end

After

array.each.with_index(1) do |item, index|
  puts index
end

Details

The cop flags the following patterns when applied to the index block parameter:

  • index + N / N + index (integer literal addition)
  • index - N (integer literal subtraction)
  • index.succ / index.next (equivalent to + 1)
  • index.pred (equivalent to - 1)

It only registers an offense when every reference to the index variable in the block body uses the same constant offset. Mixed usage (e.g. both index + 1 and bare index) is not flagged, which keeps autocorrection safe.

Supported call forms

Call form Behavior
each_with_index { |_, i| i + N } Offense — corrects to each.with_index(N)
each.with_index { |_, i| i + N } Offense — corrects to each.with_index(N)
each.with_index(0) { |_, i| i + N } Offense — corrects to each.with_index(N)
each.with_index(5) { |_, i| i + N } No offense (non-zero offset already present)

Configuration

Style/WithIndexOffset:
  Description: 'Checks for offset arithmetic on the index variable inside `each_with_index` or `with_index` blocks.'
  Enabled: pending
  VersionAdded: '<<next>>'

Test coverage

23 specs covering:

  • All offset patterns (+ N, N +, - N, .succ, .next, .pred)
  • All call forms (each_with_index, each.with_index, each.with_index(0))
  • Autocorrection for each pattern
  • Safe navigation (&.)
  • Multiple usages with same offset
  • Single-line brace blocks
  • Numbered parameter blocks (Ruby 2.7+ numblocks)
  • it-parameter blocks (Ruby 3.4+ itblocks)
  • No-offense cases: bare index, mixed usage, different offsets, non-zero existing offset, variable offsets, empty body, single block argument, unused index

Both Parser and Prism engines pass. The cop also detected and corrected 5 instances in the RuboCop codebase itself.

The cop is safe to disable on a per-line basis for patterns like array subscript peek-ahead where the original form may be more readable.

@justindell justindell force-pushed the add-style-with-index-offset branch from 56b75e0 to b73a851 Compare March 5, 2026 17:12
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 5, 2026

This pull request has been automatically marked as stale because it has not had any recent activity. It will be closed soon if no further activity occurs. Thank you for your contribution and understanding!

@github-actions github-actions Bot added the stale Issues that haven't been active in a while label Apr 5, 2026
@justindell
Copy link
Copy Markdown
Author

Any thoughts on this cop from anyone?

@github-actions github-actions Bot removed the stale Issues that haven't been active in a while label Apr 5, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

This pull request has been automatically marked as stale because it has not had any recent activity. It will be closed soon if no further activity occurs. Thank you for your contribution and understanding!

@github-actions github-actions Bot added the stale Issues that haven't been active in a while label May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale Issues that haven't been active in a while

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant