byebug 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/GUIDE.md +231 -0
  4. data/README.md +195 -7
  5. data/bin/byebug +1 -5
  6. data/byebug.gemspec +34 -35
  7. data/lib/byebug.rb +2 -5
  8. data/lib/byebug/command.rb +13 -13
  9. data/lib/byebug/commands/breakpoints.rb +1 -1
  10. data/lib/byebug/commands/control.rb +1 -1
  11. data/lib/byebug/commands/frame.rb +1 -1
  12. data/lib/byebug/commands/info.rb +1 -1
  13. data/lib/byebug/commands/list.rb +5 -5
  14. data/lib/byebug/commands/reload.rb +7 -10
  15. data/lib/byebug/commands/{irb.rb → repl.rb} +49 -13
  16. data/lib/byebug/commands/set.rb +10 -6
  17. data/lib/byebug/commands/show.rb +4 -7
  18. data/lib/byebug/commands/trace.rb +2 -2
  19. data/lib/byebug/context.rb +3 -5
  20. data/lib/byebug/helper.rb +2 -2
  21. data/lib/byebug/interface.rb +3 -0
  22. data/lib/byebug/processor.rb +2 -2
  23. data/lib/byebug/version.rb +1 -1
  24. data/old_doc/byebug.1 +1 -2
  25. data/old_doc/byebug.texi +125 -126
  26. data/old_doc/hanoi.rb +2 -3
  27. data/old_doc/triangle.rb +6 -7
  28. data/test/breakpoints_test.rb +43 -33
  29. data/test/display_test.rb +1 -1
  30. data/test/edit_test.rb +20 -15
  31. data/test/eval_test.rb +32 -26
  32. data/test/examples/list.rb +12 -1
  33. data/test/frame_test.rb +56 -43
  34. data/test/help_test.rb +11 -8
  35. data/test/info_test.rb +18 -13
  36. data/test/list_test.rb +74 -80
  37. data/test/method_test.rb +1 -3
  38. data/test/reload_test.rb +3 -3
  39. data/test/repl_test.rb +112 -0
  40. data/test/restart_test.rb +72 -70
  41. data/test/set_test.rb +43 -27
  42. data/test/show_test.rb +97 -102
  43. data/test/source_test.rb +6 -10
  44. data/test/stepping_test.rb +45 -49
  45. data/test/support/test_dsl.rb +47 -55
  46. data/test/test_helper.rb +2 -2
  47. data/test/trace_test.rb +4 -4
  48. data/test/variables_test.rb +10 -8
  49. metadata +9 -10
  50. data/old_doc/Makefile +0 -20
  51. data/test/examples/edit2.rb +0 -3
  52. data/test/irb_test.rb +0 -85
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c587e41bb9bea57e9e9cc27cec5d670fb7d66f81
4
- data.tar.gz: b565d9e7848ef7772edfcc9521f4e11accc50ef6
3
+ metadata.gz: 889f4fe2a663bd2b3f7bf9d03f6b82971cfcb3ad
4
+ data.tar.gz: 1d8c1667bb48110e5cca851b5f50a799fa0b54dc
5
5
  SHA512:
6
- metadata.gz: e8cc31ecfc37cfeac40245ef53ca93eb88f6902821fb698374dd48dbe21c1bb97a203e565c0021cc97aca5b3b67fdc1a18b424cefa945f2dd0dfd75dfb08f0f6
7
- data.tar.gz: 8ec279d81317f14ac91289c7a11776b931fe6931069c5acfe39cd422f2cce994b3940abb5548dda6493a3a58fc8a7c2d7f52ad43cb971b7fcda4ad27192c2344
6
+ metadata.gz: 6f268a0212666405a1f80188575158ad64d19853e11950bc50decf2a36b81eecca3565513e068bb004a391038354a0f016226e561e12a4988e213993a773345e
7
+ data.tar.gz: 1cf89b9b021e749a06cbe2141146b632846d7cd7d1f21f584870967fb85f8e278195050829e16380cbc6bc1d4ab92bc79c62966872275819752b113ccd89ef30
@@ -1,9 +1,16 @@
1
+ ## 1.2.0
2
+
3
+ * Added 'pry' command.
4
+ * Ctrl+C during command line editing is handled and works like pry/irb
5
+
6
+
1
7
  ## 1.1.1
2
8
 
3
9
  * Better help system
4
10
  * Code cleanup
5
11
  * First version compatible with pry-byebug
6
12
 
13
+
7
14
  ## 1.1.0
8
15
 
9
16
  * Post mortem support
@@ -0,0 +1,231 @@
1
+ ## Second Sample Session: Delving Deeper
2
+
3
+ In this section we'll introduce breakpoints, the call stack and restarting.
4
+ Below we will debug a simple Ruby program to solve the classic Towers of Hanoi
5
+ puzzle. It is augmented by the bane of programming: some command-parameter
6
+ processing with error checking.
7
+
8
+ ```
9
+ $ byebug hanoi.rb
10
+ [1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb
11
+ 1: # Solves the classic Towers of Hanoi puzzle.
12
+ => 2: def hanoi(n,a,b,c)
13
+ 3: if n-1 > 0
14
+ 4: hanoi(n-1, a, c, b)
15
+ 5: end
16
+ 6: puts "Move disk %s to %s" % [a, b]
17
+ 7: if n-1 > 0
18
+ 8: hanoi(n-1, c, b, a)
19
+ 9: end
20
+ 10: end
21
+ (byebug)
22
+ ```
23
+
24
+ Recall in the first section iwe said that before the `def` is run, the method it
25
+ names is undefined. Let's check that out. First let's see what private methods
26
+ we can call before running `def hanoi`.
27
+
28
+ ```
29
+ (byebug) private_methods
30
+ [:public, :private, :include, :using, :define_method, :default_src_encoding, ...
31
+ ```
32
+
33
+ `private_methods` is not a byebug command but a Ruby feature. By default, when
34
+ byebug doesn't understand a command, it will evaluate it as if it was a Ruby
35
+ command. If you don't want this behaviour, you can use `set autoeval off` or
36
+ even drop it in your `.byebugrc` file if you want that behaviour permanently.
37
+ The output of `private_methods`, thought, is unwieldy for our porpuse: check
38
+ whether `hanoi` method is in the list. Fortunately, byebug has nice formatting
39
+ features: we can sort the output and put it into columns list using the print
40
+ command `ps`.
41
+
42
+ ```
43
+ (byebug) ps private_methods
44
+ Array debug_program open sprintf
45
+ Complex default_src_encoding p srand
46
+ DelegateClass define_method pp syscall
47
+ Digest eval print system
48
+ Float exec printf test
49
+ Hash exit private throw
50
+ Integer exit! proc trace_var
51
+ Pathname fail process_options trap
52
+ Rational fork public untrace_var
53
+ String format putc using
54
+ __callee__ gem puts warn
55
+ __dir__ gem_original_require raise whence_file
56
+ __method__ gets rand
57
+ ` global_variables readline
58
+ abort include readlines
59
+ at_exit initialize require
60
+ autoload initialize_clone require_relative
61
+ autoload? initialize_copy respond_to_missing?
62
+ binding initialize_dup select
63
+ block_given? iterator? set_trace_func
64
+ caller lambda singleton_method_added
65
+ caller_locations load singleton_method_removed
66
+ catch local_variables singleton_method_undefined
67
+ dbg_print loop sleep
68
+ dbg_puts method_missing spawn
69
+ (byebug)
70
+ ```
71
+
72
+ Now let's see what happens after stepping:
73
+
74
+ ```
75
+ (byebug) private_methods.member?(:hanoi)
76
+ false
77
+ (byebug:1) step
78
+ [7, 16] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb
79
+ 7: if n-1 > 0
80
+ 8: hanoi(n-1, c, b, a)
81
+ 9: end
82
+ 10: end
83
+ 11:
84
+ => 12: i_args=ARGV.length
85
+ 13: if i_args > 1
86
+ 14: puts "*** Need number of disks or no parameter"
87
+ 15: exit 1
88
+ 16: end
89
+ (byebug) private_methods.member?(:hanoi)
90
+ true
91
+ (byebug)
92
+ ```
93
+
94
+ Okay, lets go on and talk about program arguments.
95
+
96
+ ```
97
+ (byebug) ARGV
98
+ []
99
+ ```
100
+
101
+ Ooops. We forgot to specify any parameters to this program. Let's try again. We can
102
+ use the `restart` command here.
103
+
104
+ ```
105
+ (byebug) restart 3
106
+ Re exec'ing:
107
+ /home/davidr/.rvm/gems/ruby-2.0.0-p195@byebug/gems/byebug-1.1.1/bin/byebug /home/davidr/Proyectos/byebug/old_doc/hanoi.rb 3
108
+ [1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb
109
+ 1: # Solves the classic Towers of Hanoi puzzle.
110
+ => 2: def hanoi(n,a,b,c)
111
+ 3: if n-1 > 0
112
+ 4: hanoi(n-1, a, c, b)
113
+ 5: end
114
+ 6: puts "Move disk %s to %s" % [a, b]
115
+ 7: if n-1 > 0
116
+ 8: hanoi(n-1, c, b, a)
117
+ 9: end
118
+ 10: end
119
+ (byebug) break 4
120
+ Created breakpoint 1 at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3
121
+ (byebug) continue
122
+ Stopped by breakpoint 1 at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3
123
+ [1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb
124
+ 1: # Solves the classic Towers of Hanoi puzzle.
125
+ 2: def hanoi(n,a,b,c)
126
+ => 3: if n-1 > 0
127
+ 4: hanoi(n-1, a, c, b)
128
+ 5: end
129
+ 6: puts "Move disk %s to %s" % [a, b]
130
+ 7: if n-1 > 0
131
+ 8: hanoi(n-1, c, b, a)
132
+ 9: end
133
+ 10: end
134
+ (byebug) display n
135
+ 1: n = 3
136
+ (byebug) display a
137
+ 2: a = a
138
+ (byebug) undisplay 2
139
+ (byebug) display a.inspect
140
+ 3: a.inspect = :a
141
+ (byebug) display b.inspect
142
+ 4: b.inspect = :b
143
+ (byebug) continue
144
+ Stopped by breakpoint 1 at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3
145
+ [1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb
146
+ 1: # Solves the classic Towers of Hanoi puzzle.
147
+ 2: def hanoi(n,a,b,c)
148
+ => 3: if n-1 > 0
149
+ 4: hanoi(n-1, a, c, b)
150
+ 5: end
151
+ 6: puts "Move disk %s to %s" % [a, b]
152
+ 7: if n-1 > 0
153
+ 8: hanoi(n-1, c, b, a)
154
+ 9: end
155
+ 10: end
156
+ 1: n = 2
157
+ 3: a.inspect = :a
158
+ 4: b.inspect = :c
159
+ (byebug) c
160
+ Stopped by breakpoint 1 at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3
161
+ [1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb
162
+ 1: # Solves the classic Towers of Hanoi puzzle.
163
+ 2: def hanoi(n,a,b,c)
164
+ => 3: if n-1 > 0
165
+ 4: hanoi(n-1, a, c, b)
166
+ 5: end
167
+ 6: puts "Move disk %s to %s" % [a, b]
168
+ 7: if n-1 > 0
169
+ 8: hanoi(n-1, c, b, a)
170
+ 9: end
171
+ 10: end
172
+ 1: n = 1
173
+ 3: a.inspect = :a
174
+ 4: b.inspect = :b
175
+ (byebug) where
176
+ --> #0 Object.hanoi(n#Fixnum, a#Symbol, b#Symbol, c#Symbol)
177
+ at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3
178
+ #1 Object.hanoi(n#Fixnum, a#Symbol, b#Symbol, c#Symbol)
179
+ at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:4
180
+ #2 Object.hanoi(n#Fixnum, a#Symbol, b#Symbol, c#Symbol)
181
+ at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:4
182
+ #3 <main> at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:34
183
+ (byebug)
184
+ ```
185
+
186
+ In the above we added new commands: `break` (see [breakpoints]()), which
187
+ indicates to stop just before that line of code is run, and `continue`, which
188
+ resumes execution. Notice the difference between `display a` and
189
+ `display a.inspect`. An implied string conversion is performed on the expression
190
+ after it is evaluated. To remove a display expression `undisplay` is used. If we
191
+ give a display number, just that display expression is removed.
192
+
193
+ We also used a new command `where`(see [Backtrace]()) to show the call stack. In
194
+ the above situation, starting from the bottom line we see we called the `hanoi`
195
+ method from line 34 of the file `hanoi.rb` and the `hanoi` method called itself
196
+ two more times at line 4.
197
+
198
+ In the call stack we show a _current frame_ mark, the frame number, the method
199
+ being called, the names of the parameters, the types those parameters
200
+ _currently_ have and the file-line position. Remember it's possible that when
201
+ the program was called the parameters had different types, since the types of
202
+ variables can change dynamically. You can alter the style of what to show in the
203
+ trace (see [Callstyle]()).
204
+
205
+ Now let's more around the callstack.
206
+
207
+ ```
208
+ (byebug) undisplay
209
+ Clear all expressions? (y/n) y
210
+ (byebug:1) i_args
211
+ NameError Exception: undefined local variable or method `i_args' for main:Object
212
+ (byebug:1) frame -1
213
+ #3 at hanoi.rb:34
214
+ (byebug:1) i_args
215
+ 1
216
+ (byebug:1) p n
217
+ 3
218
+ (byebug:1) down 2
219
+ #1 Object.hanoi(n#Fixnum, a#Symbol, b#Symbol, c#Symbol) at hanoi.rb:4
220
+ (byebug:1) p n
221
+ 2
222
+ ```
223
+
224
+ Notice in the above to get the value of variable `n` we had to use a print
225
+ command like `p n`. If we entered just `n`, that would be taken to mean byebug
226
+ command ``next''. In the current scope, variable `i_args` is not defined.
227
+ However I can change to the top-most frame by using the `frame` command. Just as
228
+ with arrays, -1 means the last one. Alternatively using frame number 3 would
229
+ have been the same thing; so would issuing `up 3`. Note that in the outside
230
+ frame #3, the value of `i_args` can be shown. Also note that the value of
231
+ variable `n` is different.
data/README.md CHANGED
@@ -1,12 +1,33 @@
1
1
  # Byebug [![Gem Version](https://badge.fury.io/rb/byebug.png)](http://badge.fury.io/rb/byebug) [![Build Status](https://secure.travis-ci.org/deivid-rodriguez/byebug.png)](http://travis-ci.org/deivid-rodriguez/byebug) [![Code Climate](https://codeclimate.com/github/deivid-rodriguez/byebug.png)](https://codeclimate.com/github/deivid-rodriguez/byebug) [![Dependency Status](https://gemnasium.com/deivid-rodriguez/byebug.png)](https://gemnasium.com/deivid-rodriguez/byebug)
2
2
 
3
- A Ruby 2.0 debugger.
3
+ _Debugging in Ruby 2.0_
4
+
5
+ Byebug is a simple to use, feature rich debugger for Ruby 2.0. It uses the new
6
+ TracePoint API, so it doesn't depend on internal core sources. It's developed as
7
+ a C extension, so it's fast. And it has a full test suite so it's (I hope)
8
+ reliable.
9
+
10
+ It allows you to see what is going on _inside_ a Ruby program while it executes
11
+ and can do four main kinds of things (plus other things in support of these) to
12
+ help you catch bugs in the act:
13
+
14
+ * Start your program or attach to it, specifying anything that might affect its
15
+ behavior.
16
+ * Make your program stop on specified conditions.
17
+ * Examine what has happened when your program has stopped.
18
+ * Change things in your program, so you can experiment with correcting the
19
+ effects of one bug and go on to learn about another.
4
20
 
5
21
 
6
22
  ## Install
7
23
 
8
- Just type `gem install byebug` or drop `gem 'byebug'` in your Gemfile and run
9
- `bundle install`.
24
+ Just drop
25
+
26
+ gem 'byebug'
27
+
28
+ in your Gemfile and run
29
+
30
+ bundle install
10
31
 
11
32
 
12
33
  ## Usage
@@ -16,14 +37,181 @@ stop there. If you are debugging rails, start the server in normal mode with
16
37
  `rails server` and once the execution get to your `byebug` command you will get
17
38
  a debugging terminal.
18
39
 
40
+ ## Getting Started
41
+
42
+ A handful of commands are enough to get started using `byebug`. The following
43
+ session illustrates these commands. Below is Ruby code to compute a triangle
44
+ number of a given length (there are shorter ways to do it, of course).
45
+
46
+ ```
47
+ $ byebug triangle.rb
48
+ [1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb
49
+ 1: # Compute the n'th triangle number: triangle(n) == (n*(n+1))/2
50
+ => 2: def triangle(n)
51
+ 3: tri = 0
52
+ 4: 0.upto(n) do |i|
53
+ 5: tri += i
54
+ 6: end
55
+ 7: tri
56
+ 8: end
57
+ 9:
58
+ 10: t = triangle(3)
59
+ (byebug)
60
+ ```
61
+
62
+ We are currently stopped before the first executable line of the program: line 2
63
+ of `triangle.rb`. If you are used to less dynamic languages and have used
64
+ debuggers for more statically compiled languages like C, C++, or Java, it may
65
+ seem odd to be stopped before a function definition but in Ruby line 2 is
66
+ executed.
67
+
68
+ Byebug's prompt is `(byebug)`. If the program has died and you are in
69
+ post-mortem debugging, `(byebug:post-mortem)` is used instead. If the program
70
+ has terminated normally, the string this position will be `(byebug:ctrl)`. The
71
+ commands available change depending on the program's state.
72
+
73
+ Byebug automatically lists 10 lines of code centered around the current line
74
+ everytime it is stopped. The current line is marked with `=>`, so the range
75
+ byebug would like to show is [-3..6]. However since there aren't 5 lines before
76
+ the current line, the range is moved _up_ so we can actually display 10 lines
77
+ of code.
78
+
79
+ Now let us step through the program.
80
+
81
+ ```
82
+ (byebug) step
83
+ [2, 11] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb
84
+ 2: def triangle(n)
85
+ 3: tri = 0
86
+ 4: 0.upto(n) do |i|
87
+ 5: tri += i
88
+ 6: end
89
+ 7: tri
90
+ 8: end
91
+ 9:
92
+ => 10: t = triangle(3)
93
+ 11: puts t
94
+ (byebug) <RET> # hit enter
95
+ [1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb
96
+ 1: # Compute the n'th triangle number: triangle(n) == (n*(n+1))/2
97
+ 2: def triangle(n)
98
+ => 3: tri = 0
99
+ 4: 0.upto(n) do |i|
100
+ 5: tri += i
101
+ 6: end
102
+ 7: tri
103
+ 8: end
104
+ 9:
105
+ 10: t = triangle(3)
106
+ (byebug) p tri
107
+ nil
108
+ (byebug) step
109
+ [1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb
110
+ 1: # Compute the n'th triangle number: triangle(n) == (n*(n+1))/2
111
+ 2: def triangle(n)
112
+ 3: tri = 0
113
+ => 4: 0.upto(n) do |i|
114
+ 5: tri += i
115
+ 6: end
116
+ 7: tri
117
+ 8: end
118
+ 9:
119
+ 10: t = triangle(3)
120
+ (byebug) p tri
121
+ 0
122
+ ```
123
+
124
+ The first `step` command runs the script one executable unit. The second command
125
+ we entered was just hitting the return key; `byebug` remembers the last command
126
+ you entered was `step` and it runs it again.
127
+
128
+ One way to print the values of variables is `p` (there are other ways). When we
129
+ look at the value of `tri` the first time, we see it is `nil`. Again we are
130
+ stopped _before_ the assignment on line 3, and this variable hasn't been set
131
+ previously. However after issuing another `step` command we see that the value
132
+ is 0 as expected. If every time we stop we want to see the value of `tri` to see
133
+ how things are going, there is a better way by setting a display expression:
134
+
135
+ ```
136
+ (byebug) display tri
137
+ 1: tri = 0
138
+ ```
139
+
140
+ Now let us run the program until we return from the function. We'll want to see
141
+ which lines get run, so we turn on _line tracing_. If we don't want whole paths
142
+ to be displayed when tracing, we can turn on _basename_.
143
+
144
+ ```
145
+ (byebug) display i
146
+ 2: i =
147
+ (byebug) set linetrace on
148
+ line tracing is on.
149
+ (byebug) set basename on
150
+ basename is on.
151
+ (byebug) finish
152
+ Tracing: triangle.rb:5 tri += i
153
+ 1: tri = 0
154
+ 2: i = 0
155
+ Tracing: triangle.rb:5 tri += i
156
+ 1: tri = 0
157
+ 2: i = 1
158
+ Tracing: triangle.rb:5 tri += i
159
+ 1: tri = 1
160
+ 2: i = 2
161
+ Tracing: triangle.rb:5 tri += i
162
+ 1: tri = 3
163
+ 2: i = 3
164
+ Tracing: triangle.rb:7 tri
165
+ 1: tri = 6
166
+ 2: i =
167
+ Tracing: triangle.rb:11 puts t
168
+ 1: tri =
169
+ 2: i =
170
+ [2, 11] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb
171
+ 2: def triangle(n)
172
+ 3: tri = 0
173
+ 4: 0.upto(n) do |i|
174
+ 5: tri += i
175
+ 6: end
176
+ 7: tri
177
+ 8: end
178
+ 9:
179
+ 10: t = triangle(3)
180
+ => 11: puts t
181
+ 1: tri =
182
+ 2: i =
183
+ (byebug) quit
184
+ Really quit? (y/n) y
185
+ ```
186
+
187
+ So far, so good. As you can see from the above to get out of `byebug`, one
188
+ can issue a `quit` command (`q` and `exit` are just as good). If you want to
189
+ quit without being prompted, suffix the command with an exclamation mark, e.g.,
190
+ `q!`.
191
+
192
+ ### The rest of the tutorial is available
193
+ [here](https://github.com/deivid-rodriguez/byebug/blob/master/GUIDE.md)
19
194
 
20
195
  ## Configuration
21
196
 
22
197
  You can automatically load some configurations at startup by dropping them in
23
- the startup file `.byebugrc`, for example, `set listsize 20`. If you are coming
24
- from [debugger](https://github.com/cldwalker/debugger), notice however that you
25
- no longer need `set autolist`, `set autoreload` and `set autoeval` because they
26
- are default options in byebug.
198
+ the startup file `.byebugrc`. For example, you can change the number of lines
199
+ listed whenever byebug stops like this:
200
+
201
+ set listsize 20
202
+
203
+ If you are coming from [debugger](https://github.com/cldwalker/debugger), notice
204
+ however that you no longer need
205
+
206
+ set autoreload
207
+
208
+ because it is a default option in byebug.
209
+
210
+
211
+ ## Related projects
212
+
213
+ * [pry-byebug](https://github.com/deivid-rodriguez/pry-byebug) adds `next`,
214
+ `step`, `finish`, `continue` and `break` commands to pry using byebug.
27
215
 
28
216
 
29
217
  ## Credits