I was just thinking about how great it would be to be able to run a program and then hit a keystroke to invoke pry and debug. Maybe there is a gem out there that injects binding.pry
dynamically during runtime that I don't know about. If there isn't, how would you make a keystroke that inserts binding.pry
before the next line of ruby script that is about to execute?
Asked
Active
Viewed 216 times
2

orde
- 5,233
- 6
- 31
- 33

David West
- 2,256
- 6
- 32
- 62
-
How would that even happen? The input handler would have to - by necessity - be running in a separate thread from your "main" code in order to process input while the program is running. Have you looked at gdb? – Chris Heald Oct 15 '14 at 15:32
1 Answers
4
Assuming a POSIX OS, you could try adding a signal handler in your ruby program. The ruby documentation even gives an example of your use case:
.. your process may trap the USR1 signal and use it to toggle debugging (http://www.ruby-doc.org/core-2.1.3/Signal.html)
Signal.trap('USR1') do
binding.pry
end
Then, to send the signal:
kill -s SIGUSR1 [pid]
Edit: A more complete example: application.rb
My naïve suggestion above will fail with a ThreadError: current thread not owner
. Here's a better example using a global $debug
flag.
#!/usr/bin/env ruby
require 'pry'
$debug = false
Signal.trap('USR1') do
puts 'trapped USR1'
$debug = true
end
class Application
def run
while true
print '.'
sleep 5
binding.pry if $debug
end
end
end
Application.new.run
This seems to work best when application.rb is running in the foreground in one shell, and you send the SIGUSR1 signal from a separate shell.
Tested in Mac OS 10.9.5. YMMV.

Jared Beck
- 16,796
- 9
- 72
- 97
-
I'm getting `unsupported signal SIGUSR1 (ArgumentError)`. I am running Cygwin, though. It is supposed to at least be partially POSIX compliant. When I type `kill -l` at the prompt, `30) SIGUSR1` is an option. Also, I haven't been able to understand where to put this. I'm running a Cucumber test suite. I threw it in the `hooks.rb` file -- if that means anything to you! Thanks :) – David West Oct 15 '14 at 21:15
-
Must be my setup... From `irb` I type `Signal.list`, I got back `{"EXIT"=>0, "INT"=>2, "ILL"=>4, "ABRT"=>22, "FPE"=>8, "KILL"=>9, "SEGV"=>11, "TERM"=>15}`. So I've only got a subset of all of the POSIX signals. – David West Oct 15 '14 at 21:18
-
For fun, see if you can co-opt one of the signals for your own purposes. However, I don't recommend co-opting INT, TERM, or SEGV, and you probably can't co-opt KILL. – Jared Beck Oct 15 '14 at 21:37
-
First update, I tried SIGINT. It actually did kinda work in that it popped me into a pry shell. It obviously terminated my process. Then i realized I wasn't running irb or cucumber from the cygwin shell. When i ran irb from cygwin all the signals were available. More tomorrow – David West Oct 16 '14 at 01:58
-
Thanks for the edit. I was about to write that I thought there needed to be more to it! Now I'm thinking about how to run this with a cucumber suite. – David West Oct 17 '14 at 12:21