pry-moves
An execution control add-on for Pry.
- Install:
gem 'pry-moves'
- For non-rails (without auto-require), add to your script:
require 'pry-moves'
Commands:
Documentation for latest version. For v0.1.12 see documentation here
-
n
- next line in current frame, including block lines (moving to next line goes as naturally expected)-
nn
- next line in current frame, skipping block lines
-
-
s
- step into function execution-
s method_name
- step into methodmethod_name
(For example fromUser.new.method_name
). Partial name match supported. -
s +
- step into function, including hidden frames
-
-
f
- finish execution of current frame (block or method) and stop at next line on higher level -
c
- continue -
b
- go to next breakpoint (methods marked withpry_breakpoint = :some_scope
variable) -
add-bp var_name [line_number]
- add to script in this place conditional breakpoint:debug if var_name == <it's value>
-
ir
- iterate, go to next iteration of current block -
g 10
- goto line 10 -
bt
- show backtrace, excluding hidden frames-
bt +
bt hidden
- show backtrace including hidden frames -
bt a
bt all
- full backtrace with system and hidden frames -
bt 10
- go to backtrace line 10 -
bt diff
- diff of backtraces (bt save
for persistent save of 1st backtrace) -
bt > foo
- write backtrace to filelog/backtrace_foo.log
-
bt ::ClassName
- list objects in backtrace which class name contains "ClassName"
-
-
up
/down
/top
/bottom
(bm
) - move over call stack-
up +
- move up, including vapid frames (block callers, hidden frames) -
up pattern
- move up till first frame which method name or file position in formatfolder/script.rb:12
matches regexp pattern
-
-
%
- print current frame of call stack (alias towhereami
) -
$
- fully print current function without line numbers -
debug some_method(some_param)
- callsome_method(some_param)
and interactively step into it. This way you can virtually "step back" by executing previous pieces of code from current method -
.method
or123
or:hash_key
- Continue traversing of last object in history. E.g.orders
will list array, then3
will enterorders[3]
, then.price
will enterorders[3].price
-
watch variable
- display variable's value on each step -
diff expression
- display difference between saved expression (on first run) and expression 2 -
profile [timeout]
- profile time-consuming code and infinite loops/recursion -
off
- Turn off debugging (don't stop on breakpoints) -
@
- restart and reload scripts (in app/ & spec/ by default), reload rake tasks. Configurable. -
#
- exit with code 3, can be wrapped in bash script to fully reload ruby scripts -
!
- exit
Variable & methods names takes precedence over commands.
So if you have variable named step
, to execute command step
type cmd step
or command's alias, e.g. s
Custom commands:
PryMoves.custom_command "say" do |args, output|
output.puts "Pry says: #{args}"
end
Examples
To use, invoke pry
normally:
def some_method
binding.pry # Execution will stop here.
puts 'Hello, World!' # Run 'step' or 'next' in the console to move here.
end
Advanced example
Demo class source here
Backtrace and call stack
You can explicitly hide frames from call stack by defining variables like this:
def insignificant_method
hide_from_stack = true
something_insignificant
yield
end
-
hide_from_stack
- hide this function from stack -
pry_moves_stack_tip
- stop on first frame above this function -
pry_moves_stack_end
- limits stack from bottom, not possible to step below this frame
Configuration
Here is default configuration, you can reassign it:
PryMoves.reload_ruby_scripts = {
monitor: %w(app spec),
except: %w(app/assets app/views)
}
PryMoves.reload_rake_tasks = true
PryMoves::Backtrace::filter =
/(\/gems\/|\/rubygems\/|\/bin\/|\/lib\/ruby\/|\/pry-moves\/)/
Turn off features with environment variables:
PRY_MOVES=off
PRY_MOVES_DEBUG_MISSING=off
PRY_MOVES_RELOADER=off
Debug:
TRACE_MOVES=on
Threads, helpers
To allow traveling to parent thread, use:
pre_callers = binding.callers
Thread.new do
Thread.current[:pre_callers] = pre_callers
#...
end
pry-moves
can't stop other threads on binding.pry
, so they will continue to run.
This makes pry-moves
not always suitable for debugging of multi-thread projects.
Though you can pause other threads with helper which will suspend execution on current line,
until ongoing debug session will be finished with continue
:
PryMoves.synchronize_threads
For example, you can put it into function which periodically reports status of thread (if you have such)
Other helpers:
-
PryMoves.open?
- if pry input dialog active. Can be used to suppress output from ongoing parallel threads
pry-remote
Rudimentary support for pry-remote
(>= 0.1.1) is also included.
Ensure pry-remote
is loaded or required before pry-moves
. For example, in a
Gemfile
:
gem 'pry'
gem 'pry-remote'
gem 'pry-moves'
Performance
Please note that debugging functionality is implemented through
set_trace_func
, which imposes heavy performance penalty while tracing
(while running code within next
/step
/finish
commands).
Development
Testing
bin/rspec
bin/rspec -f d # Output result of each spec example
DEBUG=true bin/rspec -e 'backtrace should backtrace'
ToDo
-
iterate
- steps in into child sub-block - should skip
Contributors
- Gopal Patel (@nixme)
- John Mair (@banister)
- Conrad Irwin (@ConradIrwin)
- Benjamin R. Haskell (@benizi)
- Jason R. Clark (@jasonrclark)
- Ivo Anjo (@ivoanjo)
Patches and bug reports are welcome. Just send a pull request or file an issue.
Acknowledgments
- Gopal Patel's pry-nav
- John Mair's pry-stack_explorer
- Ruby stdlib's debug.rb
- @Mon-Ouie's pry_debug