WhyChain
A tiny gem to inspect Ruby method dispatch at runtime.
WhyChain helps you see:
- method lookup chain (
ancestors) - method owner resolution
- where
superwould resolve next
Built for learning and debugging Ruby internals. Not a production framework.
You can inspect this manually in Ruby console, but WhyChain gives you a consistent, teachable trace in one call.
Installation
Add the gem to your Gemfile:
gem "why_chain"
Then run:
bundle install
Quick start
trace = WhyChain.trace(object, :method_name)
pp trace.to_h
trace is a WhyChain::DispatchTrace object with readers:
lookup_chainownernext_super_owner
As hash:
trace.to_h
# {
lookup_chain: [...],
owner: SomeClassOrModule,
next_super_owner: AnotherClassOrModule
# }
Usage examples
1) prepend vs include in runtime lookup
module P
def foo = :p
end
module I
def foo = :i
end
class A
def foo = :a
end
class B < A
include I
prepend P
end
trace = WhyChain.trace(B.new, :foo)
pp trace.to_h
# {
# lookup_chain: [P, B, I, A, Object, Kernel, BasicObject],
# owner: P,
# next_super_owner: I
# }
2) Singleton method takes precedence
obj = Object.new
def obj.single_foo = :singleton
trace = WhyChain.trace(obj, :single_foo)
pp trace.to_h
# {
# lookup_chain: [#<Class:#<Object:...>>, Object, Kernel, BasicObject],
# owner: #<Class:#<Object:...>>,
# next_super_owner: nil
# }
3) Missing method fails fast
WhyChain.trace(Object.new, :not_existing_method)
# raises NameError
Note: some entries in lookup_chain can appear as anonymous classes/modules (for example singleton classes). This is expected and reflects Ruby runtime internals.
Development
Run tests:
bundle exec rspec
Run lint:
bundle exec rubocop
Contributing
Bug reports and pull requests are welcome on GitHub: https://github.com/alessio-salati/why_chain
License
The gem is available as open source under the terms of the MIT License.