class Report
def quarterly_totals = …
def legacy_totals = …
end quarterly_totals is reached through public_send every day and
legacy_totals has no caller. The counts in this picture illustrate pooled production
traffic, which needs the hosted graph. The output below is from the example app.
The problem
dead_api lists Report#legacy_totals as having no caller in any recorded run. That is not proof
that the method is unused, because your suite doesn’t run the month-end rake task, the admin export,
or the webhook a partner hits twice a year. Any of them might call legacy_totals, and grep does
not show whether they do. This is app/controllers/reports_controller.rb in the example app:
class ReportsController < ApplicationController
def show
report = Report.new(params[:account_id])
render plain: report.public_send("#{params[:kind]}_totals").to_s
end
end
"#{params[:kind]}_totals" becomes a method name at runtime, so nobody can prove from the source
that legacy_totals is safe to delete. The method stays, and it is tested, documented and kept
through every refactor.
The fix
ra prod_dead_api asks the same question of the app runs, with spec trees left out:
$ ra prod_dead_api app/models/report.rb
prod_dead_api app/models/report.rb
· pooled from 2 recorded runs · 150 app-run trees
Report#initialize 2 app-run callers: ReportsController#show 31 calls, DashboardController#show 30 calls
· Report#legacy_totals: no app-run caller
app/models/report.rb:6
→ safe to delete
Report#quarterly_totals 1 app-run caller: ReportsController#show via public_send 31 calls
· Report#csv_rows: no app-run caller
app/models/report.rb:14
→ only spec callers
… rows, build, render and footer_text, each with spec callers only
Report#summary_line 1 app-run caller: Report#summary 62 calls
Report#summary 1 app-run caller: DashboardController#show 31 calls
quarterly_totals looked equally dead locally, and the app runs show a controller reaching it
through public_send 31 times. legacy_totals had no caller in any run or from any entry
point. Delete it:
class Report
def quarterly_totals = totals_for(:quarter)
def csv_rows = rows.map(&:to_csv)
end
How it works
The recorder wraps every method your app defines, so a call is recorded however it was made:
directly, through send or public_send, from a callback or from a name built out of a string.
Every call tree is stamped with its entry point, so the tool sets aside the trees from spec examples
and counts the request and job trees.
prod_dead_api lists each public method in the file, from the source, with its app-run callers. A
method with none is flagged, and the report says whether specs called it, so you know to delete
those specs along with the method.
Two additions are planned. One is pooling the recordings of every deploy into one hosted graph, so that the summary counts deploys and days where it now counts two recorded runs. The other is a “last called” column, which needs timestamps the recorder does not write yet.
Run it on your app
The output on this page comes from our example Rails app, and it is regenerated whenever a tool
changes. These are the commands behind it. On your own app, run ra record first, then put your
own class, method or file in their place.
ra prod_dead_api app/models/report.rb
The dead method is app/models/report.rb:6, and the public_send is app/controllers/reports_controller.rb:4.
Reading the result
- The evidence covers the period you recorded. A method called once a year needs a year of recording to be seen, and the report says how many runs and trees it pooled.
- It sees the processes you record. A worker fleet or a service that you did not run under the recorder can still call a method that nothing else calls.
Every tool reads the same recording. What gets recorded and how far to trust an answer are on the questions page.
Related tools
dead_api
Find dead public API. The public methods that no caller reached in any recorded run, including those whose only caller is their own spec. Shown as a hint in your editor.
See more →what_calls
The callers of a method. Every caller of a method in the recorded runs, with the file and line of each call and how often it was made, including calls made through public_send. what_it_calls lists the methods it calls.
See more →coupling_map
Coupling measured from app runs. Which modules and namespaces of your app call each other, and how many times, counted from recorded app runs.
See more →