Skip to content

Conversation

@davidrunger
Copy link
Contributor

@davidrunger davidrunger commented Mar 11, 2025

Fix #1465

This change avoids the printing of warnings about some methods (included, on_class, and on_send) of the RuboCop::Cop::EnforceSuperclass module being redefined. These warnings are printed because, in addition to the definition of that module here in rubocop-rails, that module is first also defined in rubocop. (The module has been extracted to rubocop-rails, but is also left in rubocop, for backwards compatibility.)

This change avoids the warnings by first undefining the RuboCop::Cop::EnforceSuperclass module (the one from rubocop) before then redefining that module here in rubocop-rails.


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. (I am not sure we can easily test this?)
  • 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.
  • If this is a new cop, consider making a corresponding update to the Rails Style Guide. (Not applicable.)

@davidrunger
Copy link
Contributor Author

davidrunger commented Mar 11, 2025

I'm not very sure that this is actually a good way to fix this issue, though it might be. But it feels sort of ugly/hacky to me.

It's extremely possible that there is some more elegant way to fix the issue. I don't even really know specifically what caused this issue to emerge in version 2.30.0, which definitely limits my ability to conceive of a more elegant fix.

If nothing else, I want to just submit this PR as a proof of concept / to illustrate the issue and a possible solution.

But I'd be very comfortable with this PR being closed, if there's some better way to fix the issue.

@davidrunger
Copy link
Contributor Author

I didn't add any tests, because I'm not really sure that we can easily test this? This repo already has RSpec configured with config.warnings = true, and yet no warnings are printed when running bundle exec rspec. I guess that the warnings appear only when rubocop-rails is required into another project?

require 'rack/utils'
require 'active_support/inflector'
String.remove_method(:blank?) if String.instance_method(:blank?)
require 'active_support/core_ext/object/blank'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

(This require statement is slightly misleading. It refers to active_support/core_ext/object/blank, but it not only patches Object, but also several other classes, including String.)

module RuboCop
module Cop
module Cop # rubocop:disable Style/Documentation
remove_const(:EnforceSuperclass) if defined?(EnforceSuperclass)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are three warnings printed about methods of EnforceSuperclass being redefined. Rather than undefining each of those three methods individually, here I just undefine the whole EnforceSuperclass module (if it is already defined). We will then (re-)define it just below.


module RuboCop
module Cop
module Cop # rubocop:disable Style/Documentation
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because this RuboCop::Cop module is no longer purely just a wrapper/namespace, since below we are adding remove_const(:EnforceSuperclass) if defined?(EnforceSuperclass) to it, RuboCop now expects a documentation comment for it. But I don't think that we really want to document this module here, so I am disabling the cop here.

@Earlopain
Copy link
Contributor

These warnings definitly have been a thing for a while already, I'm not sure why you only got them now. Tests here don't catch it because rubocop is already loaded before rspec can do its thing with warnings = true.

I don't think your solution is the right thing to do. It removes the warnings but you might as well temporarily set $VERBOSE to achieve the same thing.

I haven't looked into the EnforceSuperclass one, but the rails core extension can just be dropped in my opinion. There's no real point in using it, and rubocop does already define blank? anyways (hence the warning). I openend #1467 as an alternative for that.

@Earlopain
Copy link
Contributor

How you handle EnforceSuperclass seems ok to me. RuboCop used to own this module but at some point it was moved to rubocop-rails and kept in rubocop itself for backwards compatibility.

Seems to be that that module here should have been scoped to a different namespace (but it wasn't, oh well). Can you add a comment that this module is also defined in RuboCop for backwards compatibility?

@davidrunger davidrunger changed the title Avoid warnings about redefined methods Avoid warnings about redefined methods in EnforceSuperclass module Mar 12, 2025
Fix #1465

This change avoids the printing of warnings about some methods
(`included`, `on_class`, and `on_send`) of the
`RuboCop::Cop::EnforceSuperclass` module being redefined. These warnings
are printed because, in addition to the definition of that module here
in `rubocop-rails`, that module is first [also defined in `rubocop`][1].
(The module has been extracted to `rubocop-rails`, but is also left in
`rubocop`, for backwards compatibility.)

[1]: https://github.com/rubocop/rubocop/blob/v1.73.2/lib/rubocop/cop/mixin/enforce_superclass.rb

This change avoids the warnings by first undefining the
`RuboCop::Cop::EnforceSuperclass` module (the one from `rubocop`) before
then redefining that module here in `rubocop-rails`.
@davidrunger
Copy link
Contributor Author

I openend #1467 as an alternative for that.

@Earlopain Sounds good. I have removed from this PR the removal of String#blank?, leaving that to be fixed by #1467.

Can you add a comment that this module is also defined in RuboCop for backwards compatibility?

Yes, good suggestion, thank you! I added this comment:

# The EnforceSuperclass module is also defined in `rubocop` (for backwards
# compatibility), so here we remove it before (re)defining it, to avoid
# warnings about methods in the module being redefined.
remove_const(:EnforceSuperclass) if defined?(EnforceSuperclass)

@koic koic merged commit 2c65962 into rubocop:master Mar 14, 2025
16 checks passed
@koic
Copy link
Member

koic commented Mar 14, 2025

Thanks!

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.

Warnings are printed about methods being redefined when running specs that require 'rubocop/rspec/support' and which set RSpec 'config.warnings = true'

3 participants