I am writing a web based debugger for Ruby, but in order to do this I need to be able to call the Ruby debugger from within a Ruby program on the server side. Has this ever been done? Is this even possible?
The end product being built will allow Ruby code to be edited, executed and stepped through using just a web browser. The ruby code that is to be debugged will be "eval"ed on the server side.
I have since been pointed in the right direction by one of the stackoverflow users who has suggested using popen or expect. I have tried bot开发者_如何学编程h of these now but have encountered the following problems:
popen: When waiting for the console you have to use a timeout block to signal the end of the debug console's output (The command line terminal can detect this, so why can't ruby).
expect: In the program below the debugger inputs get out of sync with the debugger. Why is that?
require 'pty' require 'expect' $expect_verbose = true PTY.spawn("rdebug deb.rb") do |from_debugger, to_debugger, pid| a=nil while ( a != "end" ) do from_debugger.expect(/\(rdb:1\)/ ) do |input| a = gets to_debugger.puts( a + "\n" ) end from_debugger.flush end end
I think you could make use of ruby-debug. I would imagine this as opening the same script on the server-side, and sending keystrokes to it. I think this is how I'd do it.
Think about it this way: the client pastes his code in your form. Optionally, he may click on some button that places a breakpoint on some line. Then he submits the whole thing. On server side, you process that form, and create a .rb file with the contents of the form. At the line where he put the breakpoint, you insert a debugger
call. Then you run :
ruby client_script.rb
and this will stop the process once it reaches the debugger
line. I would suggest you do all of this with Expect for Ruby or whatever. So, when the client presses step over
on the page or inspect whatever variable, you send keystrokes to the process you spawned.
For example, if he wants to inspect the value of the variable x
, you'd send this to the process:
p x
and you'd have to capture that output and send it back to the client's browser. Expect
is kind of like popen
, but a bit better.
I finally figured out how to do this using expect:
require 'pty' require 'expect' PTY.spawn("rdebug deb.rb") do |output,input,pid| while true do begin buffer = "" puts "-------" puts output.readpartial(1024,buffer) until buffer =~ /\(rdb:1\)/ a = gets input.puts a rescue break end end end
精彩评论