Skip to content

Commit

Permalink
Fix Style/BlockDelimiters for blocks with numbered arguments
Browse files Browse the repository at this point in the history
With `EnforcedStyle` of `line_count_based`, the default, the following
code **will** issue an offense, and will be auto-corrected:

```ruby
[1, 2, 3].map { |n| # [1, 2, 3].map do |n|
  n + 1             #   n + 1
}                   # end

```

While the code below won't be converted to a multiline `do ... end`
block:

```ruby
[1, 2, 3].map {
  _1 + 1
}
```

This is yet another case of missing `on_numblock` implementation. I see
a dozen of those in the codebase and I think whenever we handle `block`
AST nodes we should also handle `numblock` nodes. I can go over the
codebase and fix those problems on a per-cop basis, or I can try to fix
it generally.

Currently, my best idea is to write an `InternalAffairs` cop that warns
when we define `on_block` handlers, but we miss a `on_block`
implementation. For the majority of the cases, an `on_numblock` alias of
the `on_block` method would be enough to handle blocks with numbered
arguments. I can then use the internal co and systematically go over the
cases and add aliases or custom `numblock` handlers where required. I
think this is better than solutions involving meta-programming or
default `on_numblock` implementations delegating to `on_block`.
  • Loading branch information
gsamokovarov committed Jun 26, 2022
1 parent 8eb4f1b commit 199c4b7
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
1 change: 1 addition & 0 deletions changelog/fix_block_delimiters_with_numbered_arguments.md
@@ -0,0 +1 @@
* [#10749](https://github.com/rubocop/rubocop/pull/10749): Fix Style/BlockDelimiters for blocks with numbered arguments. ([@gsamokovarov][])
4 changes: 3 additions & 1 deletion lib/rubocop/cop/style/block_delimiters.rb
Expand Up @@ -184,6 +184,8 @@ def on_block(node)
end
end

alias on_numblock on_block

private

def autocorrect(corrector, node)
Expand Down Expand Up @@ -300,7 +302,7 @@ def with_block?(node)

def get_blocks(node, &block)
case node.type
when :block
when :block, :numblock
yield node
when :send
get_blocks(node.receiver, &block) if node.receiver
Expand Down
29 changes: 29 additions & 0 deletions spec/rubocop/cop/style/block_delimiters_spec.rb
Expand Up @@ -27,6 +27,35 @@
}, 1
RUBY
end

context 'Ruby >= 2.7', :ruby27 do
it 'registers an offense for a single line numblock with do-end' do
expect_offense(<<~RUBY)
each do _1 end
^^ Prefer `{...}` over `do...end` for single-line blocks.
RUBY
end

it 'accepts a single line numblock with braces' do
expect_no_offenses('each { _1 }')
end

it 'accepts a multi-line numblock with do-end' do
expect_no_offenses(<<~RUBY)
each do
_1
end
RUBY
end

it 'accepts a multi-line numblock that needs braces to be valid ruby' do
expect_no_offenses(<<~RUBY)
puts [1, 2, 3].map {
_1 * _1
}, 1
RUBY
end
end
end

context 'EnforcedStyle: semantic' do
Expand Down

0 comments on commit 199c4b7

Please sign in to comment.