Rubocop: Is there a way to add custom deprecated methods on the DeprecatedClassMethods?

Created on 22 Jan 2020  路  5Comments  路  Source: rubocop-hq/rubocop

Question

I would like to know if I can add custom deprecated methods to Rubocop DeprecatedClassMethods cops. We wrote a custom cop to add this ability in our project. So, can we do that?

If no, what do you think about that?
If yes, can you share some tips with me? I read the Ruby Docs from the Cop and some Google Search but I couldn't find anything.

Why?

We use this solution to help us envolve our codebase through all the teams.

Most helpful comment

Let's say we want to deprecate Book#find() and Book#find_by(id:) (Doesn't make much sense, but does make a point :eyes:). It'd be nice to have something like this in the config:

Lint/DeprecateMethods:
  Enabled: true
  Rules:
    - Class: Book
      Method: find
      Replacement: 'BookRepository.find_by_custom_id!'
    - Class: Book
      Method: find_by
      ArgumentName: id
      Replacement: 'BookRepository.find_by_custom_id!'

And maybe have Class also be optional.

All 5 comments

As of now, there isn't a way to add custom deprecated methods. The original intention behind the cop was to flag deprecated class methods from Ruby itself. I can see where there would be value to allow users to specify some custom deprecations as well. Someone would need to come up with a good system of how to register the custom deprecations and their replacement.

This cop seems to have left its original intention already. I just noticed that it checks for iterator? which isn't a class method. If we allow custom deprecations, we may want to rename the cop while we are at it. Identifying class methods is significantly easier than identifying other methods because of the added context of the method call on a specific class.

I see a lot of value on it. It is a common scenario on living codebases.

We have a custom cop doing it for us. If you want, I can contact the cop developer and ask if she wants to share it with us.

In our custom cop, you can define the deprecated class, the method, the arguments and a replacement itself.

Let's say we want to deprecate Book#find() and Book#find_by(id:) (Doesn't make much sense, but does make a point :eyes:). It'd be nice to have something like this in the config:

Lint/DeprecateMethods:
  Enabled: true
  Rules:
    - Class: Book
      Method: find
      Replacement: 'BookRepository.find_by_custom_id!'
    - Class: Book
      Method: find_by
      ArgumentName: id
      Replacement: 'BookRepository.find_by_custom_id!'

And maybe have Class also be optional.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution and understanding!

This could be quite useful, but I'd venture to say that most deprecated methods will be instance methods, not class methods.

A cop with inline nodepattern could be a more generic solution:

Lint/OurDeprecations:
  Inline:
  - Pattern: '(send #global_const(:Book) :find! $_id)
    AutoCorrect: 'Book.find_by_custom_id!($1)'
    Message: 'Use Book.find_by_custom_id!'
  - Pattern: '(send #global_const(:Book) :find_by! (hash (pair (sym :id) $_id)))'
    AutoCorrect: 'Book.find_by_custom_id!($1)'
    Message: 'Use Book.find_by_custom_id!'

We could allow instance methods with a grep on the name of the receiver, e.g.:

  - Pattern: '(send ${(send _ /books/) (lvar /books/)} :find! $_id))'
    AutoCorrect: '$1.find_by_custom_id!($2)'
    Message: 'Use Book.find_by_custom_id!'

That could flag something like Bookstore.catalog.current_books.find("hitchhiker's guide to the galaxy") and even auto-correct it to Bookstore.catalog.current_books.find_by_custom_id!("hitchhiker's guide to the galaxy")

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ecbrodie picture ecbrodie  路  3Comments

Aqualon picture Aqualon  路  3Comments

millisami picture millisami  路  3Comments

bbugh picture bbugh  路  3Comments

deivid-rodriguez picture deivid-rodriguez  路  3Comments