rubocop/rubocop

Naming/PredicateMethod: more detailed introspection of the method body

Open

#14.256 aperta il 7 giu 2025

Vedi su GitHub
 (8 commenti) (1 reazione) (1 assegnatario)Ruby (3103 fork)batch import
feature requestgood first issue

Metriche repository

Star
 (12.857 star)
Metriche merge PR
 (Merge medio 2g 8h) (158 PR mergiate in 30 g)

Descrizione

Is your feature request related to a problem? Please describe.

One more idea/suggestion about Naming/PredicateName after trying to apply it to a large codebase. There is one widespread pattern that triggers the cop which feels "wrong":

def do_something
  return false unless should_be_done?

  internal_do_something

  true
end

I.e., the main thing about the method is side effects, but it also returns booleans indicating whether it has invoked something or not. It shouldn't be named like a predicate, but the cop will suggest so.

Describe the solution you'd like

How can we filter out those methods? It is not very simple but pretty straightforward:

  • starting from each return value
  • go back through statements in the method body
  • ...and check if this statement assigns some value used to calculate the return value; if not, it is not a predicate.

E.g., this is not a predicate:

def foo
  File.write('test.log', some_data) # this doesn't participate in result

  true
end

...and this is a predicate:

def foo
  data = File.read('test.log', some_data) # this is used to calculate the next line
  line = data.find { it.include?('ERROR:') } # this is used to calculate value used for result

  line.match?('not found') # start analysis from here
end

It will still miss edge cases like this (side effect is present, but doesn't look like it

def foo
  some_complicated_side_effect(lot, of, params) == :success
end

...but so will the human, so rubocop:disable in this case + appropriate comment would be helpful :)

Guida contributor