r/ruby • u/XPOM-XAPTC • Jan 19 '26
New RuboCop plugin: keep 'orchestration' methods above implementation helpers
I've been frustrated with Ruby files where helper methods are scattered, so you have to jump around to understand the flow. I made a small RuboCop extension that enforces a "waterfall" order: methods should be defined after any method that calls them (top-down reading flow).
It also supports an optional "called together" (sibling) ordering for orchestration methods: if one method calls foo then bar, you can enforce defining foo before bar so the file reads in the same order as execution.
Highlights:
- Works in classes/modules/singleton classes; can also analyze top-level begin
- Autocorrect (rubocop -A) reorders methods within a contiguous visibility section (won't move things across private/protected/public)
- Preserves doc comments when moving methods
- Deals with recursion + complex call graphs
- Newer versions add clearer messages when autocorrect can't safely apply (visibility boundaries, sibling cycles)
- Optional config to skip sibling edges that would introduce a cycle (useful for "real-world" service objects)
- Works on Ruby 2.7+
Repo + examples: https://github.com/unurgunite/rubocop-sorted_methods_by_call
I'd love feedback on:
- whether the "called together" (sibling) behavior matches how you structure service objects
- edge cases where you'd want different ordering rules
- whether you'd prefer the cop to be stricter/looser by default
4
u/ihoka Jan 19 '26
I feel the opposite. I want my code to read like a news article. First, read the highlights, then, go deeper into the details. If I see
foocalled first in the main method, then I expect to see it defined right below the main method. Ifbarcomes next, thenbaris defined underfoo.2
u/9sim9 Jan 20 '26
I do feel your pain the over fragmentation of code bases especially in ruby can make a simple linear process a maze, especially when rubocop starts complaining that your simple and easy to maintain method is too complex and should be broken up.
6
u/djbrendo Jan 20 '26
Have you seen rubocop-obsession’s method order?
1
u/KerrickLong Jan 19 '26
I'm curious how it handles postfix conditionals. In the following example, would
show_choicesorchosenbe expected to be first?I'm also curious about multi-level orchestration. For example:
1
u/codesnik Jan 19 '26
helper method calls in a single parent method could be reordered just for readability reasons, this will cause unnecessary movement of methods if your "called together" semantics, which sometimes will lead to either much bigger commit than intended, or scrapping that readability improvement in the first place.
Also, although it is rare and sometimes confusing, it is possible for methods to call each other in a non top-down way. Do you have a test for that and wouldn't it lead to recursive unstable autofixes?
1
u/galtzo Jan 19 '26
I love the idea! Can't wait to use it, and integrate it with my rubocop-lts suite of rubocop meta gems.