-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Don't use #send
etc. to include or prepend modules
#7274
Labels
Comments
8 tasks
I think it makes sense because it can be unified with a new mix-in style using public |
koic
added a commit
to koic/rubocop
that referenced
this issue
Aug 12, 2019
Resolves rubocop#7274. This PR adds new `Lint/SendWithMixinArgument` cop. This cop checks for `send`, `public_send`, and `__send__` methods when using mix-in. ```ruby # bad Foo.send(:include, Bar) Foo.send(:prepend, Bar) Foo.send(:extend, Bar) # bad Foo.public_send(:include, Bar) Foo.public_send(:prepend, Bar) Foo.public_send(:extend, Bar) # bad Foo.__send__(:include, Bar) Foo.__send__(:prepend, Bar) Foo.__send__(:extend, Bar) # good Foo.include Bar Foo.prepend Bar Foo.extend Bar ``` `include` and `prepend` methods were private methods until Ruby 2.0, they were mixed-in via `send` method. This cop uses Ruby 2.1 or higher style that can be called by public methods. ```console % ruby -v ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-darwin13.0.2] % ruby -e 'module M end; Object.include(M)' -e:1:in `<main>': private method `include' called for Object:Class (NoMethodError) % ruby -e 'module M end; Object.prepend(M)' -e:1:in `<main>': private method `prepend' called for Object:Class (NoMethodError) % ruby -v ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-darwin13.0] % ruby -e 'module M end; Object.include(M)' # no error % ruby -e 'module M end; Object.prepend(M)' # no error ``` And `extend` method that was originally a public method is also targeted for style unification. ```console % ruby -v ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-darwin13.0.2] % ruby -e 'module M end; Object.extend(M)' # no error % ruby -v ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-darwin13.0] % ruby -e 'module M end; Object.extend(M)' # no error ```
bbatsov
pushed a commit
that referenced
this issue
Aug 13, 2019
Resolves #7274. This PR adds new `Lint/SendWithMixinArgument` cop. This cop checks for `send`, `public_send`, and `__send__` methods when using mix-in. ```ruby # bad Foo.send(:include, Bar) Foo.send(:prepend, Bar) Foo.send(:extend, Bar) # bad Foo.public_send(:include, Bar) Foo.public_send(:prepend, Bar) Foo.public_send(:extend, Bar) # bad Foo.__send__(:include, Bar) Foo.__send__(:prepend, Bar) Foo.__send__(:extend, Bar) # good Foo.include Bar Foo.prepend Bar Foo.extend Bar ``` `include` and `prepend` methods were private methods until Ruby 2.0, they were mixed-in via `send` method. This cop uses Ruby 2.1 or higher style that can be called by public methods. ```console % ruby -v ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-darwin13.0.2] % ruby -e 'module M end; Object.include(M)' -e:1:in `<main>': private method `include' called for Object:Class (NoMethodError) % ruby -e 'module M end; Object.prepend(M)' -e:1:in `<main>': private method `prepend' called for Object:Class (NoMethodError) % ruby -v ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-darwin13.0] % ruby -e 'module M end; Object.include(M)' # no error % ruby -e 'module M end; Object.prepend(M)' # no error ``` And `extend` method that was originally a public method is also targeted for style unification. ```console % ruby -v ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-darwin13.0.2] % ruby -e 'module M end; Object.extend(M)' # no error % ruby -v ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-darwin13.0] % ruby -e 'module M end; Object.extend(M)' # no error ```
7 tasks
tijmenb
added a commit
to tijmenb/mail-notify
that referenced
this issue
Oct 21, 2019
This trips over a Rubocop rule on CI: ``` lib/mail/notify/railtie.rb:12:36: W: Lint/SendWithMixinArgument: Use prepend Mail::Notify::MailersController instead of send(:prepend, Mail::Notify::MailersController). Rails::MailersController.send(:prepend, Mail::Notify::MailersController) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``` As rubocop/rubocop#7274 explains: > Back in the day (before Ruby 2.1), Module.include and Module.prepend were private methods. So when people authored gems / patched monkeys, they wrote e.g. Foo.send(:include, MyPatch). In our day and age, I think we should encourage everybody to just write Foo.include(MyPatch).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Back in the day (before Ruby 2.1),
Module.include
andModule.prepend
were private methods. So when people authored gems / patched monkeys, they wrote e.g.Foo.send(:include, MyPatch)
. In our day and age, I think we should encourage everybody to just writeFoo.include(MyPatch)
.Describe the solution you'd like
Recommend calling
Foo.include(Bar)
overFoo.send(:include, Bar)
,Foo.public_send(:include, M)
, etc.Recommend calling
Foo.prepend(Bar)
overFoo.send(:prepend, Bar)
,Foo.public_send(:prepend, M)
, etc.Describe alternatives you've considered
None
Additional context
None
The text was updated successfully, but these errors were encountered: