Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new Lint/ConstantDefinitionInBlock cop #8707

Merged
merged 1 commit into from Sep 13, 2020

Conversation

eugeneius
Copy link
Contributor

Constants defined within a block are added to the current lexical scope, which means the block has no effect on where the constant is defined or how it can be accessed. I often see constants defined inside Rake tasks or RSpec describe blocks where the intent was clearly for them to be scoped to the block, but which actually leak into the top-level scope.


Before submitting the PR make sure the following are checked:

  • 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.
  • Added an entry to the Changelog if the new code introduces user-observable changes. See changelog entry format.
  • The PR relates to only one subject with a clear title and description in grammatically correct, complete sentences.
  • Run bundle exec rake default. It executes all tests and RuboCop for itself, and generates the documentation.

# describe 'making a request' do
# let(:test_request) { Class.new }
# end
class ConstantDefinedInBlock < Base
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably we should name this ConstantDefinitionInBlock to be more consistent with existing cop names.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, I updated the name.

@bbatsov
Copy link
Collaborator

bbatsov commented Sep 12, 2020

Nice cop! I think we should also mention this in the Ruby Style Guide, as it might not be super obvious to some people.

Constants defined within a block are added to the current lexical scope,
which means the block has no effect on where the constant is defined or
how it can be accessed. I often see constants defined inside Rake tasks
or RSpec `describe` blocks where the intent was clearly for them to be
scoped to the block, but which actually leak into the top-level scope.
@eugeneius eugeneius changed the title Add new Lint/ConstantDefinedInBlock cop Add new Lint/ConstantDefinitionInBlock cop Sep 12, 2020
@eugeneius
Copy link
Contributor Author

I opened rubocop/ruby-style-guide#841 to add a corresponding guideline to the Ruby Style Guide.

@bbatsov bbatsov merged commit 5ff83df into rubocop:master Sep 13, 2020
@bbatsov
Copy link
Collaborator

bbatsov commented Sep 13, 2020

Thanks! I'll merge the cop as it is, as I might cut a new release today, but we should add a link to the new guideline to the cop metadata.

koic added a commit to koic/rubocop-rails that referenced this pull request Sep 13, 2020
Follow rubocop/rubocop#8707

This PR suppresses the following RuboCop's offense.

```console
% bundle exec rake
(snip)

Offenses:

spec/rubocop/cop/active_record_helper_spec.rb:6:3: W:
Lint/ConstantDefinitionInBlock: Do not define constants within a block.
  module RuboCop ...
    ^^^^^^^^^^^^^^

185 files inspected, 1 offense detected, 1 offense auto-correctable
RuboCop failed!
```
jmkoni pushed a commit to standardrb/standard that referenced this pull request Sep 16, 2020
…en fixed

* Update Rubocop from
  [0.90](https://github.com/rubocop-hq/rubocop/releases/tag/v0.90.0)
  to
  [0.91](https://github.com/rubocop-hq/rubocop/releases/tag/v0.91.0),
  enabling:
  * [`Lint/UselessTimes`](rubocop/rubocop#8702)
  * [`Layout/BeginEndAlignment`](rubocop/rubocop#8628)
  * [`Lint/ConstantDefinitionInBlock`](rubocop/rubocop#8707)
  * [`Lint/IdentityComparison`](rubocop/rubocop#8699)
  re-enabling after bug fixes:
  * [`Bundler/DuplicatedGem`](rubocop/rubocop#8666)
  * [`Naming/BinaryOperatorParameterName`](rubocop/rubocop#8664)
@ghiculescu
Copy link
Contributor

FYI for anyone who comes across this, this cop isn't compatible with sorbet. Specifically, constants defined in blocks are how enums work.

@marcandre do you want me to do a docs PR for this one too?

@marcandre
Copy link
Contributor

@marcandre do you want me to do a docs PR for this one too?

Yes, that would be a great starting point. At a minimum we should document these cases, and afterwards see what is the best to address them. In this case, we could exclude enum do, or have an allowlist, for example...

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.

None yet

4 participants