Calltally
Tally your method calls.
A simple yet powerful tool to analyze method usage in Ruby/Rails codebases. Quickly identify your most-used methods, understand code patterns, and make informed refactoring decisions.
Installation
Add to your Gemfile:
gem 'calltally', group: :development
Or install globally:
gem install calltally
Quick Start
# Analyze current directory
calltally
# Analyze specific directory
calltally app/models
# Show top 20 results
calltally --top 20
# Focus on specific classes
calltally --receivers User,Post --top 10
Usage Examples
Rails Projects
Calltally automatically detects Rails projects and scans the right directories:
# Auto-detects Rails and scans app/, lib/, config/
calltally
# Analyze specific file patterns
calltally app/models
# Focus on ActiveRecord methods
calltally --methods where,find,joins --mode pairs
Output Formats
# Default table format
calltally
# JSON format for further processing
calltally --format json > analysis.json
# CSV for spreadsheet analysis
calltally --format csv -o results.csv
Filtering and Analysis
# Show only method names (no receivers)
calltally --mode methods
# Show only receivers (classes being called)
calltally --mode receivers
# Show receiver-method pairs (default)
calltally --mode pairs
# Include methods called without explicit receivers
calltally --include-nil-receiver
Configuration
Create .calltally.yml in your project root for persistent settings:
# .calltally.yml
profile: rails # auto|rails|default
dirs: # Directories to scan
- app
- lib
exclude: # Patterns to exclude
- spec
- test
- vendor
top: 50 # Number of results to show
mode: pairs # pairs|methods|receivers
skip_operators: true # Skip operators like +, -, ==
You can also use a custom config file:
calltally --config config/calltally-production.yml
Advanced Usage
Filter by Variable Types
```bash # Only local variables calltally --only-locals # Only instance variables calltally --only-ivars # Only class/module constants calltally --only-constants # Class variables calltally --only-cvars # Global variables calltally --only-gvars # Combine filters calltally --only-locals --only-constants # Show variable names instead of grouping calltally --split-variables # Shows: (var:user).name instead of (var).name ```All CLI Options
``` calltally [PATH] [options] Options: --profile PROFILE auto|rails|default (default: auto) -d, --dirs x,y Directories to include -x, --exclude x,y Path parts to exclude -n, --top N Show top N results (default: 100) -v, --verbose Verbose output --mode MODE Output mode: - pairs: receiver-method pairs (default) - methods: method names only - receivers: receiver names only --receivers x,y Filter by receiver constants (e.g. User,Post) --methods x,y Filter by method names (e.g. where,find) --include-nil-receiver Count calls without explicit receiver --split-variables Show variable names (e.g. '(var:user)' vs '(var)') --only-locals Show only local variable receivers --only-ivars Show only instance variable receivers --only-cvars Show only class variable receivers --only-gvars Show only global variable receivers --only-constants Show only constant receivers --[no-]skip-operators Skip operator methods like +, -, ==, [] (default: true) --format FORMAT Output format: table|json|csv (default: table) -o, --output PATH Write result to file instead of STDOUT --config PATH Use a specific config file -h, --help Show help ```Understanding the Output
Calltally shows method calls in your codebase with their receivers:
10 User.where # User class, where method, called 10 times
5 (var).each # Local variable, each method, called 5 times
3 (ivar).save # Instance variable, save method
2 Post#.validate # validate called within Post class (implicit receiver)
Receiver Types
User- Class or module constant(var)- Local variable (use--split-variablesto see names)(ivar)- Instance variable(cvar)- Class variable(gvar)- Global variable(self)- Explicit self receiver(result)- Method calls on results (e.g.,user.posts.first→(var).posts+(result).first)#- Implicit receiver (when using--include-nil-receiver)
Use Cases
- Find most-used methods - Identify candidates for optimization
- Understand code patterns - See how your team uses APIs
- Refactoring decisions - Know what methods are heavily depended upon
- API design - Understand which methods are actually used
- Code reviews - Quickly analyze unfamiliar codebases
- Gem development - See how your gem's methods are used
FAQ
Why does grep show different counts than CallTally?
CallTally counts method calls, not all text occurrences:
grep "Current.user"finds bothCurrent.user(getter) andCurrent.user = value(setter)- CallTally only counts
Current.user(the getter method call) - Setters like
name=are separate methods and not counted asname
Which file types are analyzed?
- Ruby files:
.rb,.ru,.rake - Not included: JavaScript, CSS, YAML, and other file types
Why do I see (result) as a receiver?
When methods are chained, CallTally shows intermediate results as (result):
user.posts.first→(var).posts+(result).first- This happens because CallTally doesn't infer types without type annotations
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/nsgc/calltally.
License
The gem is available as open source under the terms of the MIT License.