Description of the issue 📄
Our RuboCop config enables Style/HashSyntax but leaves EnforcedShorthandSyntax at the default either, which accepts both styles. During review of #2832 this came up: when a hash keyword matches a same-named local variable or method, the idiomatic modern Ruby (3.1+) form is shorthand — write member: instead of member: member.
# shorthand: key name matches the variable/method name
described_class.with(member:).chaser.deliver_now
Fabricate(:subscription, member:, group: students_group)
# longhand stays: value is an expression or differently-named variable
Fabricate(:member_email_delivery, member:, email_type: action_name)
Enforcing it mechanically means reviewer preferences no longer need to be remembered — the linter carries the rule.
Size: with EnforcedShorthandSyntax: always, the current codebase produces 466 offenses across 367 files — every single one autocorrectable.
Steps to fix 🛠
- In
.rubocop.yml, set the option on the existing cop:
Style/HashSyntax:
EnforcedShorthandSyntax: always
- Run the sweep — all offenses are marked
[Correctable]:
- No
.rubocop_todo.yml entry is needed: the sweep fixes the whole backlog, so nothing is deferred.
To do 📋
Description of the issue 📄
Our RuboCop config enables
Style/HashSyntaxbut leavesEnforcedShorthandSyntaxat the defaulteither, which accepts both styles. During review of #2832 this came up: when a hash keyword matches a same-named local variable or method, the idiomatic modern Ruby (3.1+) form is shorthand — writemember:instead ofmember: member.Enforcing it mechanically means reviewer preferences no longer need to be remembered — the linter carries the rule.
Size: with
EnforcedShorthandSyntax: always, the current codebase produces 466 offenses across 367 files — every single one autocorrectable.Steps to fix 🛠
.rubocop.yml, set the option on the existing cop:[Correctable]:.rubocop_todo.ymlentry is needed: the sweep fixes the whole backlog, so nothing is deferred.To do 📋