Best way to debug third-party gems in ruby
I would love to know if there's a better way to do this, but how I usually do it is:
- Add the ruby-debug gem to your Gemfile (or ruby-debug19 if you're on Ruby 1.9.2)
- Find the Gem by doing
bundle show gemname
. I'm on a Mac so I usually pipe this to pbcopy so it gets copied to my clipboard.bundle show rails | pbcopy
- Open the gem directory in your favorite editor.
mvim /path/to/gem/directory
- Navigate to the file and line where you want to put the breakpoint* and insert
debugger
above the line in question. - Reload page, run test, or do whatever you would to get the Gem file to execute
- When execution stops at debugger, you can inspect variables (
p variable_name
), and move line by line with the ruby debugger commands.
*Knowing where to put the breakpoint can take some understanding of the code, but you should start in lib/gemname.rb
Process for debugging a third-party gem
Use :path
in the project's gemfile.
You are working on gem my_gem
and project my_project
at the same time. To make this painless use this in the gemfile of your project
# in /path/to/my_project/Gemfile
...
gem 'my_gem', :path => '/path/to/my_gem'
...
And then you can iterate without having to build the gem all time.
There's isn't even a need to rename the gem.
How to debug a plugin / gem? (with useful notes to setup and use ruby-debug gem)
I highly recommend you learn to use ruby-debug. You can install it by doing:
gem install ruby-debug
You can then add a debugger
statement to your code either in the plugin code or where your code calls the plugin, step through it, and see what's going wrong.
I also personally use these settings which makes it a bit easier to use - put them in a ~/.rdebugrc
file.
set autoeval
set autolist
set autoreload
rails: How to log response & request of 3rd party gem?
As it says in the active_shipping docs:
To log requests and responses, just set the logger on your carrier class to some kind of Logger object:
ActiveShipping::USPS.logger = Logger.new($stdout)
Can I access the source of a ruby block without &block?
So, the real issue here is that I didn't read all the Pry help (specifically rescue-pry) and didn't know about the up
command...
Usage: up [OPTIONS]
Go up to the caller's context. Accepts optional numeric parameter for how many frames to move up.
Also accepts a string (regex) instead of numeric; for jumping to nearest parent method frame which matches the regex.
e.g: up #=> Move up 1 stack frame.
e.g: up 3 #=> Move up 2 stack frames.
e.g: up meth #=> Jump to nearest parent stack frame whose method matches /meth/ regex, i.e `my_method`.
-h, --help Show this message.
By executing up
within a pry
session from a raised exception, I was able to get to the block where the exception was raised and inspect the local variables I needed.
Related Topics
Problems with the Rails Console, Rvm and Readline
Flattening Nested Hash to a Single Hash with Ruby/Rails
Split String into a List, But Keeping the Split Pattern
Generate a Powerset of a Set Without Keeping a Stack in Erlang or Ruby
Rvm Is Not a Function, Selecting Rubies with 'Rvm Use ...' Will Not Work
How Does Shovel (<<) Operator Work in Ruby Hashes
Using Join Tables in Ruby on Rails
How to Require Active Record Working Outside of Rails
Why Does Array.Slice Behave Differently for (Length, N)
How to Dynamically Alter Inheritance in Ruby
Portable Ruby on Rails Environment