Class: Teek::Debugger
- Inherits:
-
Object
- Object
- Teek::Debugger
- Defined in:
- lib/teek/debugger.rb
Overview
Live inspector for Teek applications. Opens a Toplevel window with three tabs: Widgets (tree + config), Variables (searchable list), and Watches (tracked variable history).
Can also be enabled via the TEEK_DEBUG environment variable.
Constant Summary collapse
- TOP =
Prefix for all debugger widget paths
".teek_debug"- NB =
"#{TOP}.nb"- WATCH_HISTORY_SIZE =
50
Instance Attribute Summary collapse
-
#interp ⇒ Object
readonly
Returns the value of attribute interp.
Instance Method Summary collapse
-
#add_watch(name) ⇒ Object
Add a variable watch by name.
- #hide ⇒ Object
-
#initialize(app) ⇒ Debugger
constructor
A new instance of Debugger.
-
#on_widget_created(path, cls) ⇒ Object
Called by App when a widget is created.
-
#on_widget_destroyed(path) ⇒ Object
Called by App when a widget is destroyed.
-
#remove_watch(name) ⇒ Object
Remove a variable watch by name.
- #show ⇒ Object
Constructor Details
#initialize(app) ⇒ Debugger
Returns a new instance of Debugger.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/teek/debugger.rb', line 20 def initialize(app) @app = app @interp = app.interp @watches = {} app.command(:toplevel, TOP) app.command(:wm, 'title', TOP, 'Teek Debugger') app.command(:wm, 'geometry', TOP, '400x500') # Don't let closing the debugger kill the app close_proc = proc { |*| app.command(:wm, 'withdraw', TOP) } app.command(:wm, 'protocol', TOP, 'WM_DELETE_WINDOW', close_proc) setup_ui start_auto_refresh # Start behind the main app window app.command(:lower, TOP, '.') end |
Instance Attribute Details
#interp ⇒ Object (readonly)
Returns the value of attribute interp.
18 19 20 |
# File 'lib/teek/debugger.rb', line 18 def interp @interp end |
Instance Method Details
#add_watch(name) ⇒ Object
Add a variable watch by name. Registers a Tcl trace so changes are recorded.
79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/teek/debugger.rb', line 79 def add_watch(name) return if @watches.key?(name) cb_id = @app.register_callback(proc { |var_name, index, *| record_watch(var_name, index) }) @app.tcl_eval("trace add variable #{Teek.make_list(name)} write {ruby_callback #{cb_id}}") @watches[name] = { cb_id: cb_id, values: [] } record_watch(name, nil) update_watches_ui end |
#hide ⇒ Object
46 47 48 |
# File 'lib/teek/debugger.rb', line 46 def hide @app.hide(TOP) end |
#on_widget_created(path, cls) ⇒ Object
Called by App when a widget is created
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/teek/debugger.rb', line 51 def (path, cls) tree = "#{NB}.widgets.tree" return unless @app.command(:winfo, 'exists', tree) == "1" return if @app.command(tree, 'exists', path) == "1" ensure_parent_exists(path) parent_id = parent_tree_id(path) name = tk_basename(path) @app.command(tree, 'insert', parent_id, 'end', id: path, text: name, values: Teek.make_list(path, cls)) @app.command(tree, 'item', parent_id, open: 1) rescue Teek::TclError => e $stderr.puts "teek debugger: on_widget_created(#{path}): #{e.message}" end |
#on_widget_destroyed(path) ⇒ Object
Called by App when a widget is destroyed
68 69 70 71 72 73 74 75 76 |
# File 'lib/teek/debugger.rb', line 68 def (path) tree = "#{NB}.widgets.tree" return unless @app.command(:winfo, 'exists', tree) == "1" return unless @app.command(tree, 'exists', path) == "1" @app.command(tree, 'delete', path) rescue Teek::TclError => e $stderr.puts "teek debugger: on_widget_destroyed(#{path}): #{e.message}" end |
#remove_watch(name) ⇒ Object
Remove a variable watch by name.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/teek/debugger.rb', line 94 def remove_watch(name) info = @watches.delete(name) return unless info @app.tcl_eval( "trace remove variable #{Teek.make_list(name)} write {ruby_callback #{info[:cb_id]}}" ) @app.unregister_callback(info[:cb_id]) # Remove the tree item watch_tree = "#{NB}.watches.tree" item_id = "watch_#{name}" if @app.command(watch_tree, 'exists', item_id) == "1" @app.command(watch_tree, 'delete', item_id) end update_watches_ui rescue Teek::TclError => e $stderr.puts "teek debugger: remove_watch(#{name}): #{e.message}" end |
#show ⇒ Object
41 42 43 44 |
# File 'lib/teek/debugger.rb', line 41 def show @app.show(TOP) @app.command(:raise, TOP) end |