KEMBAR78
Fix false negatives for `Style/NumberedParameters` and `ItBlockParameter` by koic · Pull Request #14527 · rubocop/rubocop · GitHub
Skip to content

Conversation

@koic
Copy link
Member

@koic koic commented Sep 16, 2025

This PR fixes false negatives for Style/NumberedParameters and ItBlockParameter when using multiline method chain with EnforcedStyle: allow_single_line.

EnforcedStyle: allow_single_line allows single-line usage, and numbered block parameters across multiple lines should be detected. This was an implementation bug, and the same_line? method should have been used instead of the single_line? or multiline? methods.


Before submitting the PR make sure the following are checked:

  • The PR relates to only one subject with a clear title and description in grammatically correct, complete sentences.
  • Wrote good commit messages.
  • Commit message starts with [Fix #issue-number] (if the related issue exists).
  • Feature branch is up-to-date with master (if not - rebase it).
  • Squashed related commits together.
  • Added tests.
  • Ran bundle exec rake default. It executes all tests and runs RuboCop on its own code.
  • Added an entry (file) to the changelog folder named {change_type}_{change_description}.md if the new code introduces user-observable changes. See changelog entry format for details.

…ter`

This PR fixes false negatives for `Style/NumberedParameters` and `ItBlockParameter`
when using multiline method chain with `EnforcedStyle: allow_single_line`.

`EnforcedStyle: allow_single_line` allows single-line usage,
and numbered block parameters across multiple lines should be detected.
This was an implementation bug, and the `same_line?` method should have been used
instead of the `single_line?` or `multiline?` methods.
@bbatsov bbatsov merged commit 58a895a into rubocop:master Sep 16, 2025
22 checks passed
@koic koic deleted the fix_false_negative_for_numblock_and_it_block_parameters.md branch September 16, 2025 06:01
@Earlopain
Copy link
Contributor

I don't agree with this change. The block is clearly only on one line, no?

I would expect this to be ok:

foo
  .baz { transform(it) }
  .bat { change(it) }

What is the point of single-line if this is rejected?

@koic
Copy link
Member Author

koic commented Sep 16, 2025

I think those cases make it less readable, so they are not suitable to allow. I think single-line refers strictly to one line on the same line.

@Earlopain
Copy link
Contributor

The offense message is specifically "Avoid using it block parameter for multi-line blocks". Especially when chaining method calls like that, naming the block argument does not add anything. I don't understand why one of these would less readable:

bar { do_something(it) }

foo
  .bar { do_something(it) }

It's only a little more indented and has a dot before it. I would consider method chaining like that one of the best use-cases for it.

@koic
Copy link
Member Author

koic commented Sep 16, 2025

AKAIK, it was introduced as a shorthand. As stated in the main point, code that should be maintained ought to be explicitly named. What it refers to cannot be known without tracing back to the receiver's name, and line-broken method calls are visually inconvenient as well.

@bbatsov
Copy link
Collaborator

bbatsov commented Sep 16, 2025

I kind of agree with @Earlopain on this point, as I also think the setting targets a single-line block, not the whole expression the block is part of. In my mind there's little difference between several chained blocks on the same line or multiple lines, so I think this will likely confuse some people.

Guess I should have thought more about the PR before merging it. My bad!

@koic
Copy link
Member Author

koic commented Sep 16, 2025

Hmm, I'm questioning whether it makes sense to evaluate this based on the blocks themselves. For example, in a case like:

articles.
  foo { ... }.
  bar { ... }

what matters for understanding what the object represents is not the method names like foo or bar, but the receiver name articles.
I’m not yet convinced that having no meaningful naming in cases like this, where the code drifts away from the receiver, contributes to single-line readability.

@bkuhlmann
Copy link

Hey. 👋 In case it helps, I'm a big fan of the more functional aspects of Ruby and was taken aback by this change. For example, the following is no longer valid (where, previously, it was):

firmware.where { attachment_data.has_key "id" }
        .select { attachment_data.get_text("id").as(:attachment_id) }
        .map(:attachment_id)
        .each { shrine_store.delete it }

I understand the arguments made here but would be in favor of what I've posted above as being valid. Each line is a step which has it's own operation (so-to-speak). The readability isn't degraded because there are four steps here which read, nicely, from top to bottom. Each is self contained. The fact that I use it in the fourth step is a matter of convenience. I don't think it detracts from readability. It's no different, in terms of readability, than if you had removed steps 1 through 3. Example:

# This would not work, functionally, but only showing for illustration purposes.
firmware.each { shrine_store.delete it }

It's the same computation, in my mind, when reading this code (yes, the receiver is different, but you have to make that computation in your mind each time you use it anyway).

At the very least, could there be an option to allow for a functional pipeline flow like this?

@franzliedke
Copy link
Contributor

I'm also surprised by this very opinionated change.

Wasn't the numbered parameters syntax introduced specifically to make multi-line block chains like the examples here be more convenient / more similar to pipe operators in other languages?

@Earlopain
Copy link
Contributor

I am glad that I am not the only one that is against this change. I openend #14565 to revert, let's hope for the best.

@bbatsov
Copy link
Collaborator

bbatsov commented Sep 26, 2025

@Earlopain Merged. As noted above - I acknowledge I misread the intention of this PR and we'll need to discuss further if any changes to the existing behavior are needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants