byebug 3.2.0 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +125 -99
  4. data/CONTRIBUTING.md +4 -6
  5. data/GUIDE.md +42 -20
  6. data/Gemfile +5 -3
  7. data/README.md +2 -3
  8. data/Rakefile +11 -7
  9. data/bin/byebug +2 -252
  10. data/byebug.gemspec +7 -4
  11. data/ext/byebug/byebug.c +17 -18
  12. data/ext/byebug/byebug.h +4 -5
  13. data/ext/byebug/context.c +37 -39
  14. data/ext/byebug/threads.c +39 -18
  15. data/lib/byebug.rb +2 -110
  16. data/lib/byebug/attacher.rb +23 -0
  17. data/lib/byebug/breakpoint.rb +60 -0
  18. data/lib/byebug/command.rb +62 -70
  19. data/lib/byebug/commands/break.rb +24 -24
  20. data/lib/byebug/commands/catchpoint.rb +18 -10
  21. data/lib/byebug/commands/condition.rb +18 -17
  22. data/lib/byebug/commands/continue.rb +17 -9
  23. data/lib/byebug/commands/delete.rb +19 -13
  24. data/lib/byebug/commands/display.rb +19 -53
  25. data/lib/byebug/commands/edit.rb +7 -4
  26. data/lib/byebug/commands/enable_disable.rb +130 -0
  27. data/lib/byebug/commands/eval.rb +40 -22
  28. data/lib/byebug/commands/finish.rb +13 -4
  29. data/lib/byebug/commands/frame.rb +65 -45
  30. data/lib/byebug/commands/help.rb +17 -18
  31. data/lib/byebug/commands/history.rb +14 -8
  32. data/lib/byebug/commands/info.rb +160 -182
  33. data/lib/byebug/commands/interrupt.rb +4 -1
  34. data/lib/byebug/commands/irb.rb +30 -0
  35. data/lib/byebug/commands/kill.rb +7 -8
  36. data/lib/byebug/commands/list.rb +71 -66
  37. data/lib/byebug/commands/method.rb +14 -6
  38. data/lib/byebug/commands/pry.rb +35 -0
  39. data/lib/byebug/commands/quit.rb +9 -6
  40. data/lib/byebug/commands/reload.rb +5 -2
  41. data/lib/byebug/commands/restart.rb +13 -9
  42. data/lib/byebug/commands/save.rb +17 -17
  43. data/lib/byebug/commands/set.rb +16 -15
  44. data/lib/byebug/commands/show.rb +10 -11
  45. data/lib/byebug/commands/source.rb +11 -5
  46. data/lib/byebug/commands/stepping.rb +38 -24
  47. data/lib/byebug/commands/threads.rb +45 -31
  48. data/lib/byebug/commands/trace.rb +22 -9
  49. data/lib/byebug/commands/undisplay.rb +45 -0
  50. data/lib/byebug/commands/variables.rb +83 -27
  51. data/lib/byebug/context.rb +25 -22
  52. data/lib/byebug/core.rb +82 -0
  53. data/lib/byebug/helper.rb +37 -28
  54. data/lib/byebug/history.rb +8 -4
  55. data/lib/byebug/interface.rb +12 -17
  56. data/lib/byebug/interfaces/local_interface.rb +11 -8
  57. data/lib/byebug/interfaces/remote_interface.rb +11 -8
  58. data/lib/byebug/interfaces/script_interface.rb +9 -6
  59. data/lib/byebug/options.rb +46 -0
  60. data/lib/byebug/processor.rb +7 -1
  61. data/lib/byebug/processors/command_processor.rb +135 -125
  62. data/lib/byebug/processors/control_command_processor.rb +23 -23
  63. data/lib/byebug/remote.rb +17 -26
  64. data/lib/byebug/runner.rb +100 -0
  65. data/lib/byebug/setting.rb +33 -8
  66. data/lib/byebug/settings/autoeval.rb +5 -15
  67. data/lib/byebug/settings/autoirb.rb +4 -1
  68. data/lib/byebug/settings/autolist.rb +5 -2
  69. data/lib/byebug/settings/autoreload.rb +5 -2
  70. data/lib/byebug/settings/autosave.rb +6 -2
  71. data/lib/byebug/settings/basename.rb +7 -2
  72. data/lib/byebug/settings/callstyle.rb +4 -1
  73. data/lib/byebug/settings/forcestep.rb +6 -3
  74. data/lib/byebug/settings/fullpath.rb +5 -2
  75. data/lib/byebug/settings/histfile.rb +5 -3
  76. data/lib/byebug/settings/histsize.rb +5 -3
  77. data/lib/byebug/settings/linetrace.rb +4 -1
  78. data/lib/byebug/settings/listsize.rb +5 -1
  79. data/lib/byebug/settings/post_mortem.rb +21 -13
  80. data/lib/byebug/settings/stack_on_error.rb +6 -2
  81. data/lib/byebug/settings/testing.rb +6 -1
  82. data/lib/byebug/settings/tracing_plus.rb +5 -1
  83. data/lib/byebug/settings/verbose.rb +13 -2
  84. data/lib/byebug/settings/width.rb +4 -1
  85. data/lib/byebug/version.rb +1 -1
  86. data/test/{break_test.rb → commands/break_test.rb} +41 -53
  87. data/test/{condition_test.rb → commands/condition_test.rb} +14 -14
  88. data/test/{continue_test.rb → commands/continue_test.rb} +0 -0
  89. data/test/{delete_test.rb → commands/delete_test.rb} +2 -2
  90. data/test/commands/display_test.rb +37 -0
  91. data/test/{edit_test.rb → commands/edit_test.rb} +0 -0
  92. data/test/{eval_test.rb → commands/eval_test.rb} +1 -0
  93. data/test/{finish_test.rb → commands/finish_test.rb} +11 -1
  94. data/test/{frame_test.rb → commands/frame_test.rb} +12 -16
  95. data/test/{help_test.rb → commands/help_test.rb} +21 -4
  96. data/test/{history_test.rb → commands/history_test.rb} +0 -0
  97. data/test/{info_test.rb → commands/info_test.rb} +5 -55
  98. data/test/{interrupt_test.rb → commands/interrupt_test.rb} +0 -0
  99. data/test/commands/irb_test.rb +28 -0
  100. data/test/{kill_test.rb → commands/kill_test.rb} +1 -1
  101. data/test/{list_test.rb → commands/list_test.rb} +1 -1
  102. data/test/{method_test.rb → commands/method_test.rb} +0 -0
  103. data/test/{post_mortem_test.rb → commands/post_mortem_test.rb} +6 -10
  104. data/test/{pry_test.rb → commands/pry_test.rb} +4 -13
  105. data/test/{quit_test.rb → commands/quit_test.rb} +4 -4
  106. data/test/{reload_test.rb → commands/reload_test.rb} +0 -0
  107. data/test/{restart_test.rb → commands/restart_test.rb} +6 -0
  108. data/test/{save_test.rb → commands/save_test.rb} +2 -2
  109. data/test/{set_test.rb → commands/set_test.rb} +9 -2
  110. data/test/{show_test.rb → commands/show_test.rb} +1 -1
  111. data/test/{source_test.rb → commands/source_test.rb} +3 -3
  112. data/test/{stepping_test.rb → commands/stepping_test.rb} +44 -35
  113. data/test/{thread_test.rb → commands/thread_test.rb} +0 -0
  114. data/test/{trace_test.rb → commands/trace_test.rb} +0 -0
  115. data/test/{display_test.rb → commands/undisplay_test.rb} +7 -45
  116. data/test/{variables_test.rb → commands/variables_test.rb} +10 -1
  117. data/test/debugger_alias_test.rb +2 -2
  118. data/test/runner_test.rb +127 -0
  119. data/test/support/matchers.rb +27 -25
  120. data/test/support/test_interface.rb +9 -5
  121. data/test/support/utils.rb +96 -101
  122. data/test/test_helper.rb +32 -20
  123. metadata +93 -68
  124. data/lib/byebug/commands/enable.rb +0 -154
  125. data/lib/byebug/commands/repl.rb +0 -126
  126. data/test/irb_test.rb +0 -47
  127. data/test/support/breakpoint.rb +0 -13
@@ -66,16 +66,15 @@ extern void add_to_locked(VALUE thread);
66
66
  extern VALUE remove_from_locked();
67
67
 
68
68
  /* functions from threads.c */
69
- extern VALUE threads_create(void);
70
- extern void threads_clear(VALUE table);
71
- extern void check_thread_contexts(void);
69
+ extern void Init_threads_table(VALUE mByebug);
70
+ extern VALUE create_threads_table(void);
71
+ extern void check_threads_table(void);
72
72
  extern void thread_context_lookup(VALUE thread, VALUE *context);
73
73
  extern void halt_while_other_thread_is_active(debug_context_t *dc);
74
74
 
75
75
  /* global variables */
76
76
  extern VALUE locker;
77
77
  extern VALUE threads;
78
- extern VALUE cThreadsTable;
79
78
 
80
79
  /* functions */
81
80
  extern void Init_context(VALUE mByebug);
@@ -117,11 +116,11 @@ typedef struct {
117
116
  enum hit_condition hit_condition;
118
117
  } breakpoint_t;
119
118
 
119
+ extern void Init_breakpoint(VALUE mByebug);
120
120
  extern VALUE catchpoint_hit_count(VALUE catchpoints, VALUE exception, VALUE *exception_name);
121
121
  extern VALUE find_breakpoint_by_pos(VALUE breakpoints, VALUE source, VALUE pos,
122
122
  VALUE binding);
123
123
  extern VALUE find_breakpoint_by_method(VALUE breakpoints, VALUE klass,
124
124
  VALUE mid, VALUE binding, VALUE self);
125
- extern void Init_breakpoint(VALUE mByebug);
126
125
 
127
126
  #endif
@@ -40,7 +40,7 @@ context_mark(void *data)
40
40
  static int
41
41
  real_stack_size()
42
42
  {
43
- return FIX2INT(rb_funcall(cContext, rb_intern("stack_size"), 1, Qtrue));
43
+ return FIX2INT(rb_funcall(cContext, rb_intern("stack_size"), 0));
44
44
  }
45
45
 
46
46
  extern VALUE
@@ -182,25 +182,19 @@ call_with_debug_inspector(struct call_with_inspection_data *data)
182
182
  close_debug_inspector, (VALUE)data);
183
183
  }
184
184
 
185
- #define FRAME_SETUP \
186
- debug_context_t *context; \
187
- VALUE frame_no; \
188
- int frame_n, stack_size; \
189
- Data_Get_Struct(self, debug_context_t, context); \
190
- if (!rb_scan_args(argc, argv, "01", &frame_no)) \
191
- frame_n = 0; \
192
- else \
193
- frame_n = FIX2INT(frame_no); \
194
- stack_size = real_stack_size(); \
195
- if (frame_n < 0 || frame_n >= stack_size) \
196
- { \
197
- rb_raise(rb_eArgError, "Invalid frame number %d, stack (0...%d)", \
198
- frame_n, stack_size - 1); \
199
- } \
185
+ #define FRAME_SETUP \
186
+ debug_context_t *context; \
187
+ VALUE frame_no; \
188
+ int frame_n; \
189
+ Data_Get_Struct(self, debug_context_t, context); \
190
+ if (!rb_scan_args(argc, argv, "01", &frame_no)) \
191
+ frame_n = 0; \
192
+ else \
193
+ frame_n = FIX2INT(frame_no);
200
194
 
201
195
  /*
202
196
  * call-seq:
203
- * context.frame_binding(frame_position=0) -> binding
197
+ * context.frame_binding(frame_position = 0) -> binding
204
198
  *
205
199
  * Returns frame's binding.
206
200
  */
@@ -214,7 +208,7 @@ Context_frame_binding(int argc, VALUE *argv, VALUE self)
214
208
 
215
209
  /*
216
210
  * call-seq:
217
- * context.frame_class(frame_position=0) -> binding
211
+ * context.frame_class(frame_position = 0) -> binding
218
212
  *
219
213
  * Returns frame's defined class.
220
214
  */
@@ -228,7 +222,7 @@ Context_frame_class(int argc, VALUE *argv, VALUE self)
228
222
 
229
223
  /*
230
224
  * call-seq:
231
- * context.frame_file(frame_position=0) -> string
225
+ * context.frame_file(frame_position = 0) -> string
232
226
  *
233
227
  * Returns the name of the file in the frame.
234
228
  */
@@ -418,32 +412,32 @@ Context_step_into(int argc, VALUE *argv, VALUE self)
418
412
 
419
413
  /*
420
414
  * call-seq:
421
- * context.step_out(frame)
415
+ * context.step_out(n_frames = 1, force = false)
422
416
  *
423
- * Stops after +n_frames+ frames are finished. Implements +finish+ and
424
- * +next+ commands. +force+ parameter (if true) ensures that the cursor will
425
- * stop in the specified frame even when there's no more instructions to run.
426
- * In that case, it will stop when the return event for that frame is
427
- * triggered.
417
+ * Stops after +n_frames+ frames are finished. +force+ parameter (if true)
418
+ * ensures that the execution will stop in the specified frame even when there
419
+ * are no more instructions to run. In that case, it will stop when the return
420
+ * event for that frame is triggered.
428
421
  */
429
422
  static VALUE
430
423
  Context_step_out(int argc, VALUE *argv, VALUE self)
431
424
  {
432
425
  int n_args, n_frames;
433
- VALUE v_frames, v_force;
426
+ VALUE v_frames, force;
434
427
  debug_context_t *context;
435
428
 
436
- n_args = rb_scan_args(argc, argv, "02", &v_frames, &v_force);
429
+ n_args = rb_scan_args(argc, argv, "02", &v_frames, &force);
437
430
  n_frames = n_args == 0 ? 1 : FIX2INT(v_frames);
438
- v_force = (n_args < 2) ? Qfalse : v_force;
439
431
 
440
432
  Data_Get_Struct(self, debug_context_t, context);
441
433
 
442
434
  if (n_frames < 0 || n_frames >= context->calced_stack_size)
443
- rb_raise(rb_eRuntimeError, "Stop frame is out of range.");
435
+ rb_raise(rb_eRuntimeError,
436
+ "You wan't to finish %d frames, but stack size is only %d",
437
+ n_frames, context->calced_stack_size);
444
438
 
445
439
  context->steps_out = n_frames;
446
- if (RTEST(v_force))
440
+ if (n_args == 2 && RTEST(force))
447
441
  CTX_FL_SET(context, CTX_FL_STOP_ON_RET);
448
442
  else
449
443
  CTX_FL_UNSET(context, CTX_FL_STOP_ON_RET);
@@ -453,17 +447,18 @@ Context_step_out(int argc, VALUE *argv, VALUE self)
453
447
 
454
448
  /*
455
449
  * call-seq:
456
- * context.step_over(lines, frame = nil, force = false)
450
+ * context.step_over(lines, frame = 0, force = false)
457
451
  *
458
452
  * Steps over +lines+ lines.
459
- * Make step over operation on +frame+, by default the current frame.
453
+ * Make step over operation on +frame+, by default the newest frame.
460
454
  * +force+ parameter (if true) ensures that the cursor moves away from the
461
455
  * current line.
462
456
  */
463
457
  static VALUE
464
458
  Context_step_over(int argc, VALUE *argv, VALUE self)
465
459
  {
466
- VALUE lines, frame, force;
460
+ int n_args, frame;
461
+ VALUE lines, v_frame, force;
467
462
  debug_context_t *context;
468
463
 
469
464
  Data_Get_Struct(self, debug_context_t, context);
@@ -471,14 +466,18 @@ Context_step_over(int argc, VALUE *argv, VALUE self)
471
466
  if (context->calced_stack_size == 0)
472
467
  rb_raise(rb_eRuntimeError, "No frames collected.");
473
468
 
474
- rb_scan_args(argc, argv, "12", &lines, &frame, &force);
475
- if (FIX2INT(frame) < 0 || FIX2INT(frame) >= context->calced_stack_size)
476
- rb_raise(rb_eRuntimeError, "Destination frame is out of range.");
469
+ n_args = rb_scan_args(argc, argv, "12", &lines, &v_frame, &force);
470
+ frame = n_args == 1 ? 0 : FIX2INT(v_frame);
471
+
472
+ if (frame < 0 || frame >= context->calced_stack_size)
473
+ rb_raise(rb_eRuntimeError,
474
+ "Destination frame (%d) is out of range (%d)",
475
+ frame, context->calced_stack_size);
477
476
 
478
477
  context->lines = FIX2INT(lines);
479
- context->dest_frame = context->calced_stack_size - FIX2INT(frame);
478
+ context->dest_frame = context->calced_stack_size - frame;
480
479
 
481
- if (RTEST(force))
480
+ if (n_args == 3 && RTEST(force))
482
481
  CTX_FL_SET(context, CTX_FL_FORCE_MOVE);
483
482
  else
484
483
  CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE);
@@ -597,7 +596,6 @@ Context_set_tracing(VALUE self, VALUE value)
597
596
  return value;
598
597
  }
599
598
 
600
-
601
599
  /* :nodoc: */
602
600
  static VALUE
603
601
  DebugThread_inherited(VALUE klass)
@@ -1,5 +1,8 @@
1
1
  #include <byebug.h>
2
2
 
3
+ /* Threads table class */
4
+ static VALUE cThreadsTable;
5
+
3
6
  static int
4
7
  t_tbl_mark_keyvalue(st_data_t key, st_data_t value, st_data_t tbl)
5
8
  {
@@ -29,8 +32,12 @@ t_tbl_free(void* data)
29
32
  xfree(t_tbl);
30
33
  }
31
34
 
35
+ /*
36
+ * Creates a numeric hash whose keys are the currently active threads and
37
+ * whose values are their associated contexts.
38
+ */
32
39
  VALUE
33
- threads_create(void)
40
+ create_threads_table(void)
34
41
  {
35
42
  threads_table_t *t_tbl;
36
43
 
@@ -39,42 +46,42 @@ threads_create(void)
39
46
  return Data_Wrap_Struct(cThreadsTable, t_tbl_mark, t_tbl_free, t_tbl);
40
47
  }
41
48
 
42
- void
43
- threads_clear(VALUE table)
44
- {
45
- threads_table_t *t_tbl;
46
-
47
- Data_Get_Struct(table, threads_table_t, t_tbl);
48
- st_clear(t_tbl->tbl);
49
- }
50
-
49
+ /*
50
+ * The condition to be in the thread's table is to be either running or
51
+ * sleeping, namely, to be Thread#alive?
52
+ */
51
53
  static int
52
54
  is_living_thread(VALUE thread)
53
55
  {
54
56
  return rb_funcall(thread, rb_intern("alive?"), 0) == Qtrue;
55
57
  }
56
58
 
59
+ /*
60
+ * Checks a single entry in the threads table.
61
+ *
62
+ * If it has no associated context or the key doesn't correspond to a living
63
+ * thread, the entry is removed from the thread's list.
64
+ */
57
65
  static int
58
- t_tbl_check_i(st_data_t key, st_data_t value, st_data_t dummy)
66
+ check_thread_i(st_data_t key, st_data_t value, st_data_t dummy)
59
67
  {
60
- VALUE thread;
61
-
62
68
  if (!value) return ST_DELETE;
63
69
 
64
- thread = (VALUE)key;
65
-
66
- if (!is_living_thread(thread)) return ST_DELETE;
70
+ if (!is_living_thread((VALUE)key)) return ST_DELETE;
67
71
 
68
72
  return ST_CONTINUE;
69
73
  }
70
74
 
75
+ /*
76
+ * Checks threads table for dead/finished threads.
77
+ */
71
78
  void
72
- check_thread_contexts(void)
79
+ check_threads_table(void)
73
80
  {
74
81
  threads_table_t *t_tbl;
75
82
 
76
83
  Data_Get_Struct(threads, threads_table_t, t_tbl);
77
- st_foreach(t_tbl->tbl, t_tbl_check_i, 0);
84
+ st_foreach(t_tbl->tbl, check_thread_i, 0);
78
85
  }
79
86
 
80
87
  void
@@ -111,3 +118,17 @@ halt_while_other_thread_is_active(debug_context_t *dc)
111
118
  else break;
112
119
  }
113
120
  }
121
+
122
+ /*
123
+ *
124
+ * Document-class: ThreadsTable
125
+ *
126
+ * == Sumary
127
+ *
128
+ * Hash table holding currently active threads and their associated contexts
129
+ */
130
+ void
131
+ Init_threads_table(VALUE mByebug)
132
+ {
133
+ cThreadsTable = rb_define_class_under(mByebug, "ThreadsTable", rb_cObject);
134
+ }
@@ -1,110 +1,2 @@
1
- require 'byebug/byebug'
2
- require 'byebug/version'
3
- require 'byebug/context'
4
- require 'byebug/interface'
5
- require 'byebug/processor'
6
- require 'byebug/setting'
7
- require 'byebug/remote'
8
- require 'stringio'
9
- require 'tracer'
10
- require 'linecache19'
11
-
12
- module Byebug
13
-
14
- # List of files byebug will ignore while debugging
15
- IGNORED_FILES = Dir.glob(File.expand_path('../**/*.rb', __FILE__))
16
-
17
- # Configuration file used for startup commands. Default value is .byebugrc
18
- INITFILE = '.byebugrc' unless defined?(INITFILE)
19
-
20
- # Stores program being debugged to make restarts possible
21
- PROG_SCRIPT = $0 unless defined?(PROG_SCRIPT)
22
-
23
- class << self
24
-
25
- # processor modules provide +handler+ object
26
- attr_accessor :handler
27
- Byebug.handler = CommandProcessor.new
28
-
29
- def source_reload
30
- hsh = 'SCRIPT_LINES__'
31
- Object.send(:remove_const, hsh) if Object.const_defined?(hsh)
32
- Object.const_set(hsh, {})
33
- end
34
-
35
- #
36
- # Add a new breakpoint
37
- #
38
- # @param [String] file
39
- # @param [Fixnum] line
40
- # @param [String] expr
41
- #
42
- def add_breakpoint(file, line, expr=nil)
43
- breakpoint = Breakpoint.new(file, line, expr)
44
- breakpoints << breakpoint
45
- breakpoint
46
- end
47
-
48
- #
49
- # Remove a breakpoint
50
- #
51
- # @param [integer] breakpoint number
52
- #
53
- def remove_breakpoint(id)
54
- breakpoints.reject! { |b| b.id == id }
55
- end
56
-
57
- def interface=(value)
58
- handler.interface = value
59
- end
60
-
61
- extend Forwardable
62
- def_delegators :"handler.interface", :print
63
-
64
- #
65
- # Runs normal byebug initialization scripts.
66
- #
67
- # Reads and executes the commands from init file (if any) in the current
68
- # working directory. This is only done if the current directory is
69
- # different from your home directory. Thus, you can have more than one init
70
- # file, one generic in your home directory, and another, specific to the
71
- # program you are debugging, in the directory where you invoke byebug.
72
- #
73
- def run_init_script(out = handler.interface)
74
- cwd_script = File.expand_path(File.join(".", INITFILE))
75
- run_script(cwd_script, out) if File.exist?(cwd_script)
76
-
77
- home_script = File.expand_path(File.join(ENV['HOME'].to_s, INITFILE))
78
- if File.exist?(home_script) and cwd_script != home_script
79
- run_script(home_script, out)
80
- end
81
- end
82
-
83
- #
84
- # Runs a script file
85
- #
86
- def run_script(file, out = handler.interface, verbose=false)
87
- interface = ScriptInterface.new(File.expand_path(file), out)
88
- processor = ControlCommandProcessor.new(interface)
89
- processor.process_commands(verbose)
90
- end
91
- end
92
- end
93
-
94
- class Exception
95
- attr_reader :__bb_file, :__bb_line, :__bb_binding, :__bb_context
96
- end
97
-
98
- module Kernel
99
- #
100
- # Enters byebug right before (or right after if _before_ is false) return
101
- # events occur. Before entering byebug the init script is read.
102
- #
103
- def byebug(steps_out = 1, before = true)
104
- Byebug.run_init_script(StringIO.new)
105
- Byebug.start
106
- Byebug.current_context.step_out(steps_out, before)
107
- end
108
-
109
- alias_method :debugger, :byebug
110
- end
1
+ require 'byebug/core'
2
+ require 'byebug/attacher'
@@ -0,0 +1,23 @@
1
+ module Byebug
2
+ # Stores program being debugged to make restarts possible
3
+ PROG_SCRIPT = $PROGRAM_NAME unless defined?(PROG_SCRIPT)
4
+ end
5
+
6
+ #
7
+ # Adds a `byebug` method to the Kernel module.
8
+ #
9
+ # Dropping a `byebug` call anywhere in your code, you get a debug prompt.
10
+ #
11
+ module Kernel
12
+ #
13
+ # Enters byebug right before (or right after if _before_ is false) return
14
+ # events occur. Before entering byebug the init script is read.
15
+ #
16
+ def byebug(steps_out = 1, before = true)
17
+ Byebug.start
18
+ Byebug.run_init_script(StringIO.new)
19
+ Byebug.current_context.step_out(steps_out, before)
20
+ end
21
+
22
+ alias_method :debugger, :byebug
23
+ end
@@ -0,0 +1,60 @@
1
+ module Byebug
2
+ #
3
+ # Implements breakpoints
4
+ #
5
+ class Breakpoint
6
+ #
7
+ # First breakpoint, in order of creation
8
+ #
9
+ def self.first
10
+ Byebug.breakpoints.first
11
+ end
12
+
13
+ #
14
+ # Last breakpoint, in order of creation
15
+ #
16
+ def self.last
17
+ Byebug.breakpoints.last
18
+ end
19
+
20
+ #
21
+ # Adds a new breakpoint
22
+ #
23
+ # @param [String] file
24
+ # @param [Fixnum] line
25
+ # @param [String] expr
26
+ #
27
+ def self.add(file, line, expr = nil)
28
+ breakpoint = Breakpoint.new(file, line, expr)
29
+ Byebug.breakpoints << breakpoint
30
+ breakpoint
31
+ end
32
+
33
+ #
34
+ # Removes a breakpoint
35
+ #
36
+ # @param [integer] breakpoint number
37
+ #
38
+ def self.remove(id)
39
+ Byebug.breakpoints.reject! { |b| b.id == id }
40
+ end
41
+
42
+ #
43
+ # True if there's no breakpoints
44
+ #
45
+ def self.none?
46
+ Byebug.breakpoints.empty?
47
+ end
48
+
49
+ #
50
+ # Prints all information associated to the breakpoint
51
+ #
52
+ def inspect
53
+ meths = %w(id pos source expr hit_condition hit_count hit_value enabled?)
54
+ values = meths.map do |field|
55
+ "#{field}: #{send(field)}"
56
+ end.join(', ')
57
+ "#<Byebug::Breakpoint #{values}>"
58
+ end
59
+ end
60
+ end