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

Avoid warnings about redefined methods in EnforceSuperclass module #1466

Merged

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.)

Sorry, something went wrong.

@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?

@@ -3,6 +3,7 @@
require 'rubocop'
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.)

@@ -1,7 +1,9 @@
# frozen_string_literal: true

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.

@@ -1,7 +1,9 @@
# frozen_string_literal: true

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 force-pushed the avoid-warnings-about-redefined-methods branch from c5dc03f to b39db86 Compare March 12, 2025 13:45
@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 davidrunger force-pushed the avoid-warnings-about-redefined-methods branch from b39db86 to f5c8ee8 Compare March 12, 2025 13:53
@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
3 participants