byebug 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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