ruby-breakpoint 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,540 +1,553 @@
1
- <?xml version="1.0" encoding="iso-8859-1"?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
-
6
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
- <head>
8
- <title>Module: Breakpoint</title>
9
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
- <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
- <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
- <script type="text/javascript">
13
- // <![CDATA[
14
-
15
- function popupCode( url ) {
16
- window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
- }
18
-
19
- function toggleCode( id ) {
20
- if ( document.getElementById )
21
- elem = document.getElementById( id );
22
- else if ( document.all )
23
- elem = eval( "document.all." + id );
24
- else
25
- return false;
26
-
27
- elemStyle = elem.style;
28
-
29
- if ( elemStyle.display != "block" ) {
30
- elemStyle.display = "block"
31
- } else {
32
- elemStyle.display = "none"
33
- }
34
-
35
- return true;
36
- }
37
-
38
- // Make codeblocks hidden by default
39
- document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
-
41
- // ]]>
42
- </script>
43
-
44
- </head>
45
- <body>
46
-
47
-
48
-
49
- <div id="classHeader">
50
- <table class="header-table">
51
- <tr class="top-aligned-row">
52
- <td><strong>Module</strong></td>
53
- <td class="class-name-in-header">Breakpoint</td>
54
- </tr>
55
- <tr class="top-aligned-row">
56
- <td><strong>In:</strong></td>
57
- <td>
58
- <a href="../files/lib/breakpoint_rb.html">
59
- lib/breakpoint.rb
60
- </a>
61
- <br />
62
- </td>
63
- </tr>
64
-
65
- </table>
66
- </div>
67
- <!-- banner header -->
68
-
69
- <div id="bodyContent">
70
-
71
-
72
-
73
- <div id="contextContent">
74
-
75
-
76
-
77
- </div>
78
-
79
- <div id="method-list">
80
- <h3 class="section-bar">Methods</h3>
81
-
82
- <div class="name-list">
83
- <a href="#M000006">activate_drb</a>&nbsp;&nbsp;
84
- <a href="#M000005">assert</a>&nbsp;&nbsp;
85
- <a href="#M000004">breakpoint</a>&nbsp;&nbsp;
86
- <a href="#M000007">deactivate_drb</a>&nbsp;&nbsp;
87
- <a href="#M000008">use_drb?</a>&nbsp;&nbsp;
88
- </div>
89
- </div>
90
-
91
- </div>
92
-
93
-
94
- <!-- if includes -->
95
-
96
- <div id="section">
97
-
98
- <div id="class-list">
99
- <h3 class="section-bar">Classes and Modules</h3>
100
-
101
- Module <a href="Breakpoint/CommandBundle.html" class="link">Breakpoint::CommandBundle</a><br />
102
- Class <a href="Breakpoint/FailedAssertError.html" class="link">Breakpoint::FailedAssertError</a><br />
103
-
104
- </div>
105
-
106
- <div id="constants-list">
107
- <h3 class="section-bar">Constants</h3>
108
-
109
- <div class="name-list">
110
- <table summary="Constants">
111
- <tr class="top-aligned-row context-row">
112
- <td class="context-item-name">Version</td>
113
- <td>=</td>
114
- <td class="context-item-value">current_version</td>
115
- <td width="3em">&nbsp;</td>
116
- <td class="context-item-desc">
117
- The Version of ruby-breakpoint you are using as String of the 1.2.3 form
118
- where the digits stand for release, major and minor version respectively.
119
-
120
- </td>
121
- </tr>
122
- </table>
123
- </div>
124
- </div>
125
-
126
-
127
-
128
- <div id="attribute-list">
129
- <h3 class="section-bar">Attributes</h3>
130
-
131
- <div class="name-list">
132
- <table>
133
- <tr class="top-aligned-row context-row">
134
- <td class="context-item-name">asserts_cause_exceptions</td>
135
- <td class="context-item-value">&nbsp;[RW]&nbsp;</td>
136
- <td class="context-item-desc">
137
- Whether an Exception should be raised on failed asserts in non-$DEBUG code
138
- or not. By default this is disabled.
139
-
140
- </td>
141
- </tr>
142
- <tr class="top-aligned-row context-row">
143
- <td class="context-item-name">optimize_asserts</td>
144
- <td class="context-item-value">&nbsp;[RW]&nbsp;</td>
145
- <td class="context-item-desc">
146
- Whether asserts should be ignored if not in debug mode. Debug mode can be
147
- enabled by running ruby with the -d switch or by setting $DEBUG to true.
148
-
149
- </td>
150
- </tr>
151
- </table>
152
- </div>
153
- </div>
154
-
155
-
156
-
157
- <!-- if method_list -->
158
- <div id="methods">
159
- <h3 class="section-bar">Public Instance methods</h3>
160
-
161
- <div id="method-M000006" class="method-detail">
162
- <a name="M000006"></a>
163
-
164
- <div class="method-heading">
165
- <a href="#M000006" class="method-signature">
166
- <span class="method-name">activate_drb</span><span class="method-args">(uri = nil, allowed_hosts = ['localhost', '127.0.0.1', '::1'], ignore_collisions = false)</span>
167
- </a>
168
- </div>
169
-
170
- <div class="method-description">
171
- <p>
172
- Will run <a href="Breakpoint.html">Breakpoint</a> in DRb mode. This will
173
- spawn a server that can be attached to via the breakpoint-client command
174
- whenever a breakpoint is executed. This is useful when you are debugging
175
- CGI applications or other applications where you can&#8217;t access debug
176
- sessions via the standard input and output of your application.
177
- </p>
178
- <p>
179
- You can specify an URI where the DRb server will run at. This way you can
180
- specify the port the server runs on. The default URI is
181
- druby://localhost:42531.
182
- </p>
183
- <p>
184
- Please note that breakpoints will be skipped silently in case the DRb
185
- server can not spawned. (This can happen if the port is already used by
186
- another instance of your application on CGI or another application.)
187
- </p>
188
- <p>
189
- Also note that by default this will only allow access from localhost. You
190
- can however specify a list of allowed hosts or nil (to allow access from
191
- everywhere). But that will still not protect you from somebody reading the
192
- data as it goes through the net.
193
- </p>
194
- <p>
195
- A good approach for getting security and remote access is setting up an SSH
196
- tunnel between the DRb service and the client. This is usually done like
197
- this:
198
- </p>
199
- <p>
200
- $ ssh -L20000:127.0.0.1:20000 -R10000:127.0.0.1:10000 example.com (This
201
- will connect port 20000 at the client side to port 20000 at the server
202
- side, and port 10000 at the server side to port 10000 at the client side.)
203
- </p>
204
- <p>
205
- After that do this on the server side: (the code being debugged) <a
206
- href="Breakpoint.html#M000006">Breakpoint.activate_drb</a>(&quot;druby://127.0.0.1:20000&quot;,
207
- &quot;localhost&quot;)
208
- </p>
209
- <p>
210
- And at the client side: ruby breakpoint_client.rb -c
211
- druby://127.0.0.1:10000 -s druby://127.0.0.1:20000
212
- </p>
213
- <p>
214
- Running through such a SSH proxy will also let you use breakpoint.rb in
215
- case you are behind a firewall.
216
- </p>
217
- <p>
218
- Detailed information about running DRb through firewalls is available at <a
219
- href="http://www.rubygarden.org/ruby?DrbTutorial">www.rubygarden.org/ruby?DrbTutorial</a>
220
- </p>
221
- <h2>Security considerations</h2>
222
- <p>
223
- Usually you will be fine when using the default druby:// URI and the
224
- default access control list. However, if you are sitting on a machine where
225
- there are local users that you likely can not trust (this is the case for
226
- example on most web hosts which have multiple users sitting on the same
227
- physical machine) you will be better off by doing client/server
228
- communication through a unix socket. This can be accomplished by calling
229
- with a drbunix:/ style URI, e.g. <tt><a
230
- href="Breakpoint.html#M000006">Breakpoint.activate_drb</a>(&#8216;drbunix:/tmp/breakpoint_server&#8217;)</tt>.
231
- This will only work on Unix based platforms.
232
- </p>
233
- <p><a class="source-toggle" href="#"
234
- onclick="toggleCode('M000006-source');return false;">[Source]</a></p>
235
- <div class="method-source-code" id="M000006-source">
236
- <pre>
237
- <span class="ruby-comment cmt"># File lib/breakpoint.rb, line 374</span>
238
- 374: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">activate_drb</span>(<span class="ruby-identifier">uri</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">allowed_hosts</span> = [<span class="ruby-value str">'localhost'</span>, <span class="ruby-value str">'127.0.0.1'</span>, <span class="ruby-value str">'::1'</span>],
239
- 375: <span class="ruby-identifier">ignore_collisions</span> = <span class="ruby-keyword kw">false</span>)
240
- 376:
241
- 377: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">false</span> <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@use_drb</span>
242
- 378:
243
- 379: <span class="ruby-identifier">uri</span> <span class="ruby-operator">||=</span> <span class="ruby-value str">'druby://localhost:42531'</span>
244
- 380:
245
- 381: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">allowed_hosts</span> <span class="ruby-keyword kw">then</span>
246
- 382: <span class="ruby-identifier">acl</span> = [<span class="ruby-value str">&quot;deny&quot;</span>, <span class="ruby-value str">&quot;all&quot;</span>]
247
- 383:
248
- 384: <span class="ruby-constant">Array</span>(<span class="ruby-identifier">allowed_hosts</span>).<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">host</span><span class="ruby-operator">|</span>
249
- 385: <span class="ruby-identifier">acl</span> <span class="ruby-operator">+=</span> [<span class="ruby-value str">&quot;allow&quot;</span>, <span class="ruby-identifier">host</span>]
250
- 386: <span class="ruby-keyword kw">end</span>
251
- 387:
252
- 388: <span class="ruby-constant">DRb</span>.<span class="ruby-identifier">install_acl</span>(<span class="ruby-constant">ACL</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">acl</span>))
253
- 389: <span class="ruby-keyword kw">end</span>
254
- 390:
255
- 391: <span class="ruby-ivar">@use_drb</span> = <span class="ruby-keyword kw">true</span>
256
- 392: <span class="ruby-ivar">@drb_service</span> = <span class="ruby-constant">DRbService</span>.<span class="ruby-identifier">new</span>
257
- 393: <span class="ruby-identifier">did_collision</span> = <span class="ruby-keyword kw">false</span>
258
- 394: <span class="ruby-keyword kw">begin</span>
259
- 395: <span class="ruby-ivar">@service</span> = <span class="ruby-constant">DRb</span>.<span class="ruby-identifier">start_service</span>(<span class="ruby-identifier">uri</span>, <span class="ruby-ivar">@drb_service</span>)
260
- 396: <span class="ruby-keyword kw">rescue</span> <span class="ruby-constant">Errno</span><span class="ruby-operator">::</span><span class="ruby-constant">EADDRINUSE</span>
261
- 397: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">ignore_collisions</span> <span class="ruby-keyword kw">then</span>
262
- 398: <span class="ruby-keyword kw">nil</span>
263
- 399: <span class="ruby-keyword kw">else</span>
264
- 400: <span class="ruby-comment cmt"># The port is already occupied by another</span>
265
- 401: <span class="ruby-comment cmt"># Breakpoint service. We will try to tell</span>
266
- 402: <span class="ruby-comment cmt"># the old service that we want its port.</span>
267
- 403: <span class="ruby-comment cmt"># It will then forward that request to the</span>
268
- 404: <span class="ruby-comment cmt"># user and retry.</span>
269
- 405: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">did_collision</span> <span class="ruby-keyword kw">then</span>
270
- 406: <span class="ruby-constant">DRbObject</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">uri</span>).<span class="ruby-identifier">collision</span>
271
- 407: <span class="ruby-identifier">did_collision</span> = <span class="ruby-keyword kw">true</span>
272
- 408: <span class="ruby-keyword kw">end</span>
273
- 409: <span class="ruby-identifier">sleep</span>(<span class="ruby-value">10</span>)
274
- 410: <span class="ruby-keyword kw">retry</span>
275
- 411: <span class="ruby-keyword kw">end</span>
276
- 412: <span class="ruby-keyword kw">end</span>
277
- 413:
278
- 414: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">true</span>
279
- 415: <span class="ruby-keyword kw">end</span>
280
- </pre>
281
- </div>
282
- </div>
283
- </div>
284
-
285
- <div id="method-M000005" class="method-detail">
286
- <a name="M000005"></a>
287
-
288
- <div class="method-heading">
289
- <a href="#M000005" class="method-signature">
290
- <span class="method-name">assert</span><span class="method-args">(context = nil) {|| ...}</span>
291
- </a>
292
- </div>
293
-
294
- <div class="method-description">
295
- <p>
296
- This asserts that the block evaluates to true. If it doesn&#8217;t evaluate
297
- to true a breakpoint will automatically be created at that execution point.
298
- </p>
299
- <p>
300
- You can disable assert checking in production code by setting
301
- Breakpoint.optimize_asserts to true. (It will still be enabled when Ruby is
302
- run via the -d argument.)
303
- </p>
304
- <p>
305
- Example:
306
- </p>
307
- <pre>
308
- person_name = &quot;Foobar&quot;
309
- assert { not person_name.nil? }
310
- </pre>
311
- <p>
312
- Note: If you want to use this method from an unit test, you will have to
313
- call it by its full name, <a
314
- href="Breakpoint.html#M000005">Breakpoint.assert</a>.
315
- </p>
316
- <p><a class="source-toggle" href="#"
317
- onclick="toggleCode('M000005-source');return false;">[Source]</a></p>
318
- <div class="method-source-code" id="M000005-source">
319
- <pre>
320
- <span class="ruby-comment cmt"># File lib/breakpoint.rb, line 248</span>
321
- 248: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">assert</span>(<span class="ruby-identifier">context</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">condition</span>)
322
- 249: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">if</span> <span class="ruby-constant">Breakpoint</span>.<span class="ruby-identifier">optimize_asserts</span> <span class="ruby-keyword kw">and</span> <span class="ruby-keyword kw">not</span> <span class="ruby-identifier">$DEBUG</span>
323
- 250: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">yield</span>
324
- 251:
325
- 252: <span class="ruby-identifier">callstack</span> = <span class="ruby-identifier">caller</span>
326
- 253: <span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">slice!</span>(<span class="ruby-value">0</span>, <span class="ruby-value">3</span>) <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">first</span>[<span class="ruby-value str">&quot;assert&quot;</span>]
327
- 254: <span class="ruby-identifier">file</span>, <span class="ruby-identifier">line</span>, <span class="ruby-identifier">method</span> = <span class="ruby-operator">*</span><span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">first</span>.<span class="ruby-identifier">match</span>(<span class="ruby-regexp re">/^(.+?):(\d+)(?::in `(.*?)')?/</span>).<span class="ruby-identifier">captures</span>
328
- 255:
329
- 256: <span class="ruby-identifier">message</span> = <span class="ruby-node">&quot;Assert failed at #{file}:#{line}#{&quot; in `#{method}'&quot; if method}.&quot;</span>
330
- 257:
331
- 258: <span class="ruby-keyword kw">if</span> <span class="ruby-constant">Breakpoint</span>.<span class="ruby-identifier">asserts_cause_exceptions</span> <span class="ruby-keyword kw">and</span> <span class="ruby-keyword kw">not</span> <span class="ruby-identifier">$DEBUG</span> <span class="ruby-keyword kw">then</span>
332
- 259: <span class="ruby-identifier">raise</span>(<span class="ruby-constant">Breakpoint</span><span class="ruby-operator">::</span><span class="ruby-constant">FailedAssertError</span>, <span class="ruby-identifier">message</span>)
333
- 260: <span class="ruby-keyword kw">end</span>
334
- 261:
335
- 262: <span class="ruby-identifier">message</span> <span class="ruby-operator">+=</span> <span class="ruby-value str">&quot; Executing implicit breakpoint.&quot;</span>
336
- 263:
337
- 264: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">context</span> <span class="ruby-keyword kw">then</span>
338
- 265: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">handle_breakpoint</span>(<span class="ruby-identifier">context</span>, <span class="ruby-identifier">message</span>, <span class="ruby-identifier">file</span>, <span class="ruby-identifier">line</span>)
339
- 266: <span class="ruby-keyword kw">end</span>
340
- 267:
341
- 268: <span class="ruby-constant">Binding</span>.<span class="ruby-identifier">of_caller</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">context</span><span class="ruby-operator">|</span>
342
- 269: <span class="ruby-identifier">handle_breakpoint</span>(<span class="ruby-identifier">context</span>, <span class="ruby-identifier">message</span>, <span class="ruby-identifier">file</span>, <span class="ruby-identifier">line</span>)
343
- 270: <span class="ruby-keyword kw">end</span>
344
- 271: <span class="ruby-keyword kw">end</span>
345
- </pre>
346
- </div>
347
- </div>
348
- </div>
349
-
350
- <div id="method-M000004" class="method-detail">
351
- <a name="M000004"></a>
352
-
353
- <div class="method-heading">
354
- <a href="#M000004" class="method-signature">
355
- <span class="method-name">breakpoint</span><span class="method-args">(id = nil, context = nil, &amp;block)</span>
356
- </a>
357
- </div>
358
-
359
- <div class="method-description">
360
- <p>
361
- This will pop up an interactive ruby session at a pre-defined break point
362
- in a Ruby application. In this session you can examine the environment of
363
- the break point.
364
- </p>
365
- <p>
366
- You can get a list of variables in the context using local_variables via
367
- <tt>local_variables</tt>. You can then examine their values by typing their
368
- names.
369
- </p>
370
- <p>
371
- You can have a look at the call stack via <tt>caller</tt>.
372
- </p>
373
- <p>
374
- The source code around the location where the breakpoint was executed can
375
- be examined via <tt>source_lines</tt>. Its argument specifies how much
376
- lines of context to display. The default amount of context is 5 lines. Note
377
- that the call to <tt>source_lines</tt> can raise an exception when it
378
- isn&#8217;t able to read in the source code.
379
- </p>
380
- <p>
381
- breakpoints can also return a value. They will execute a supplied block for
382
- getting a default return value. A custom value can be returned from the
383
- session by doing +throw(:debug_return, value)+.
384
- </p>
385
- <p>
386
- You can also give names to break points which will be used in the message
387
- that is displayed upon execution of them.
388
- </p>
389
- <p>
390
- Here&#8217;s a sample of how breakpoints should be placed:
391
- </p>
392
- <pre>
393
- class Person
394
- def initialize(name, age)
395
- @name, @age = name, age
396
- breakpoint(&quot;Person#initialize&quot;)
397
- end
398
-
399
- attr_reader :age
400
- def name
401
- breakpoint(&quot;Person#name&quot;) { @name }
402
- end
403
- end
404
-
405
- person = Person.new(&quot;Random Person&quot;, 23)
406
- puts &quot;Name: #{person.name}&quot;
407
- </pre>
408
- <p>
409
- And here is a sample debug session:
410
- </p>
411
- <pre>
412
- Executing break point &quot;Person#initialize&quot; at file.rb:4 in `initialize'
413
- irb(#&lt;Person:0x292fbe8&gt;):001:0&gt; local_variables
414
- =&gt; [&quot;name&quot;, &quot;age&quot;, &quot;_&quot;, &quot;__&quot;]
415
- irb(#&lt;Person:0x292fbe8&gt;):002:0&gt; [name, age]
416
- =&gt; [&quot;Random Person&quot;, 23]
417
- irb(#&lt;Person:0x292fbe8&gt;):003:0&gt; [@name, @age]
418
- =&gt; [&quot;Random Person&quot;, 23]
419
- irb(#&lt;Person:0x292fbe8&gt;):004:0&gt; self
420
- =&gt; #&lt;Person:0x292fbe8 @age=23, @name=&quot;Random Person&quot;&gt;
421
- irb(#&lt;Person:0x292fbe8&gt;):005:0&gt; @age += 1; self
422
- =&gt; #&lt;Person:0x292fbe8 @age=24, @name=&quot;Random Person&quot;&gt;
423
- irb(#&lt;Person:0x292fbe8&gt;):006:0&gt; exit
424
- Executing break point &quot;Person#name&quot; at file.rb:9 in `name'
425
- irb(#&lt;Person:0x292fbe8&gt;):001:0&gt; throw(:debug_return, &quot;Overriden name&quot;)
426
- Name: Overriden name
427
- </pre>
428
- <p>
429
- <a href="Breakpoint.html">Breakpoint</a> sessions will automatically have a
430
- few convenience methods available. See <a
431
- href="Breakpoint/CommandBundle.html">Breakpoint::CommandBundle</a> for a
432
- list of them.
433
- </p>
434
- <p>
435
- Breakpoints can also be used remotely over sockets. This is implemented by
436
- running part of the IRB session in the application and part of it in a
437
- special client. You have to call <a
438
- href="Breakpoint.html#M000006">Breakpoint.activate_drb</a> to enable
439
- support for remote breakpoints and then run breakpoint_client.rb which is
440
- distributed with this library. See the documentation of <a
441
- href="Breakpoint.html#M000006">Breakpoint.activate_drb</a> for details.
442
- </p>
443
- <p><a class="source-toggle" href="#"
444
- onclick="toggleCode('M000004-source');return false;">[Source]</a></p>
445
- <div class="method-source-code" id="M000004-source">
446
- <pre>
447
- <span class="ruby-comment cmt"># File lib/breakpoint.rb, line 110</span>
448
- 110: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">breakpoint</span>(<span class="ruby-identifier">id</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">context</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
449
- 111: <span class="ruby-identifier">callstack</span> = <span class="ruby-identifier">caller</span>
450
- 112: <span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">slice!</span>(<span class="ruby-value">0</span>, <span class="ruby-value">3</span>) <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">first</span>[<span class="ruby-value str">&quot;breakpoint&quot;</span>]
451
- 113: <span class="ruby-identifier">file</span>, <span class="ruby-identifier">line</span>, <span class="ruby-identifier">method</span> = <span class="ruby-operator">*</span><span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">first</span>.<span class="ruby-identifier">match</span>(<span class="ruby-regexp re">/^(.+?):(\d+)(?::in `(.*?)')?/</span>).<span class="ruby-identifier">captures</span>
452
- 114:
453
- 115: <span class="ruby-identifier">message</span> = <span class="ruby-value str">&quot;Executing break point &quot;</span> <span class="ruby-operator">+</span> (<span class="ruby-identifier">id</span> <span class="ruby-value">? </span><span class="ruby-node">&quot;#{id.inspect} &quot;</span> <span class="ruby-operator">:</span> <span class="ruby-value str">&quot;&quot;</span>) <span class="ruby-operator">+</span>
454
- 116: <span class="ruby-node">&quot;at #{file}:#{line}&quot;</span> <span class="ruby-operator">+</span> (<span class="ruby-identifier">method</span> <span class="ruby-value">? </span><span class="ruby-node">&quot; in `#{method}'&quot;</span> <span class="ruby-operator">:</span> <span class="ruby-value str">&quot;&quot;</span>)
455
- 117:
456
- 118: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">context</span> <span class="ruby-keyword kw">then</span>
457
- 119: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">handle_breakpoint</span>(<span class="ruby-identifier">context</span>, <span class="ruby-identifier">message</span>, <span class="ruby-identifier">file</span>, <span class="ruby-identifier">line</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
458
- 120: <span class="ruby-keyword kw">end</span>
459
- 121:
460
- 122: <span class="ruby-constant">Binding</span>.<span class="ruby-identifier">of_caller</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">binding_context</span><span class="ruby-operator">|</span>
461
- 123: <span class="ruby-identifier">handle_breakpoint</span>(<span class="ruby-identifier">binding_context</span>, <span class="ruby-identifier">message</span>, <span class="ruby-identifier">file</span>, <span class="ruby-identifier">line</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
462
- 124: <span class="ruby-keyword kw">end</span>
463
- 125: <span class="ruby-keyword kw">end</span>
464
- </pre>
465
- </div>
466
- </div>
467
- </div>
468
-
469
- <div id="method-M000007" class="method-detail">
470
- <a name="M000007"></a>
471
-
472
- <div class="method-heading">
473
- <a href="#M000007" class="method-signature">
474
- <span class="method-name">deactivate_drb</span><span class="method-args">()</span>
475
- </a>
476
- </div>
477
-
478
- <div class="method-description">
479
- <p>
480
- Deactivates a running <a href="Breakpoint.html">Breakpoint</a> service.
481
- </p>
482
- <p><a class="source-toggle" href="#"
483
- onclick="toggleCode('M000007-source');return false;">[Source]</a></p>
484
- <div class="method-source-code" id="M000007-source">
485
- <pre>
486
- <span class="ruby-comment cmt"># File lib/breakpoint.rb, line 418</span>
487
- 418: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">deactivate_drb</span>
488
- 419: <span class="ruby-constant">Thread</span>.<span class="ruby-identifier">exclusive</span> <span class="ruby-keyword kw">do</span>
489
- 420: <span class="ruby-ivar">@service</span>.<span class="ruby-identifier">stop_service</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-ivar">@service</span>.<span class="ruby-identifier">nil?</span>
490
- 421: <span class="ruby-ivar">@service</span> = <span class="ruby-keyword kw">nil</span>
491
- 422: <span class="ruby-ivar">@use_drb</span> = <span class="ruby-keyword kw">false</span>
492
- 423: <span class="ruby-ivar">@drb_service</span> = <span class="ruby-keyword kw">nil</span>
493
- 424: <span class="ruby-keyword kw">end</span>
494
- 425: <span class="ruby-keyword kw">end</span>
495
- </pre>
496
- </div>
497
- </div>
498
- </div>
499
-
500
- <div id="method-M000008" class="method-detail">
501
- <a name="M000008"></a>
502
-
503
- <div class="method-heading">
504
- <a href="#M000008" class="method-signature">
505
- <span class="method-name">use_drb?</span><span class="method-args">()</span>
506
- </a>
507
- </div>
508
-
509
- <div class="method-description">
510
- <p>
511
- Returns true when Breakpoints are used over DRb. <a
512
- href="Breakpoint.html#M000006">Breakpoint.activate_drb</a> causes this to
513
- be true.
514
- </p>
515
- <p><a class="source-toggle" href="#"
516
- onclick="toggleCode('M000008-source');return false;">[Source]</a></p>
517
- <div class="method-source-code" id="M000008-source">
518
- <pre>
519
- <span class="ruby-comment cmt"># File lib/breakpoint.rb, line 429</span>
520
- 429: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">use_drb?</span>
521
- 430: <span class="ruby-ivar">@use_drb</span> <span class="ruby-operator">==</span> <span class="ruby-keyword kw">true</span>
522
- 431: <span class="ruby-keyword kw">end</span>
523
- </pre>
524
- </div>
525
- </div>
526
- </div>
527
-
528
-
529
- </div>
530
-
531
-
532
- </div>
533
-
534
-
535
- <div id="validator-badges">
536
- <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
537
- </div>
538
-
539
- </body>
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>Module: Breakpoint</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="classHeader">
50
+ <table class="header-table">
51
+ <tr class="top-aligned-row">
52
+ <td><strong>Module</strong></td>
53
+ <td class="class-name-in-header">Breakpoint</td>
54
+ </tr>
55
+ <tr class="top-aligned-row">
56
+ <td><strong>In:</strong></td>
57
+ <td>
58
+ <a href="../files/lib/breakpoint_rb.html">
59
+ lib/breakpoint.rb
60
+ </a>
61
+ <br />
62
+ </td>
63
+ </tr>
64
+
65
+ </table>
66
+ </div>
67
+ <!-- banner header -->
68
+
69
+ <div id="bodyContent">
70
+
71
+
72
+
73
+ <div id="contextContent">
74
+
75
+
76
+
77
+ </div>
78
+
79
+ <div id="method-list">
80
+ <h3 class="section-bar">Methods</h3>
81
+
82
+ <div class="name-list">
83
+ <a href="#M000009">activate_drb</a>&nbsp;&nbsp;
84
+ <a href="#M000008">assert</a>&nbsp;&nbsp;
85
+ <a href="#M000007">breakpoint</a>&nbsp;&nbsp;
86
+ <a href="#M000010">deactivate_drb</a>&nbsp;&nbsp;
87
+ <a href="#M000011">use_drb?</a>&nbsp;&nbsp;
88
+ </div>
89
+ </div>
90
+
91
+ </div>
92
+
93
+
94
+ <!-- if includes -->
95
+
96
+ <div id="section">
97
+
98
+ <div id="class-list">
99
+ <h3 class="section-bar">Classes and Modules</h3>
100
+
101
+ Module <a href="Breakpoint/CommandBundle.html" class="link">Breakpoint::CommandBundle</a><br />
102
+ Class <a href="Breakpoint/FailedAssertError.html" class="link">Breakpoint::FailedAssertError</a><br />
103
+
104
+ </div>
105
+
106
+ <div id="constants-list">
107
+ <h3 class="section-bar">Constants</h3>
108
+
109
+ <div class="name-list">
110
+ <table summary="Constants">
111
+ <tr class="top-aligned-row context-row">
112
+ <td class="context-item-name">Version</td>
113
+ <td>=</td>
114
+ <td class="context-item-value">current_version</td>
115
+ <td width="3em">&nbsp;</td>
116
+ <td class="context-item-desc">
117
+ The Version of ruby-breakpoint you are using as String of the 1.2.3 form
118
+ where the digits stand for release, major and minor version respectively.
119
+
120
+ </td>
121
+ </tr>
122
+ </table>
123
+ </div>
124
+ </div>
125
+
126
+
127
+
128
+ <div id="attribute-list">
129
+ <h3 class="section-bar">Attributes</h3>
130
+
131
+ <div class="name-list">
132
+ <table>
133
+ <tr class="top-aligned-row context-row">
134
+ <td class="context-item-name">asserts_cause_exceptions</td>
135
+ <td class="context-item-value">&nbsp;[RW]&nbsp;</td>
136
+ <td class="context-item-desc">
137
+ Whether an Exception should be raised on failed asserts in non-$DEBUG code
138
+ or not. By default this is disabled.
139
+
140
+ </td>
141
+ </tr>
142
+ <tr class="top-aligned-row context-row">
143
+ <td class="context-item-name">optimize_asserts</td>
144
+ <td class="context-item-value">&nbsp;[RW]&nbsp;</td>
145
+ <td class="context-item-desc">
146
+ Whether asserts should be ignored if not in debug mode. Debug mode can be
147
+ enabled by running ruby with the -d switch or by setting $DEBUG to true.
148
+
149
+ </td>
150
+ </tr>
151
+ </table>
152
+ </div>
153
+ </div>
154
+
155
+
156
+
157
+ <!-- if method_list -->
158
+ <div id="methods">
159
+ <h3 class="section-bar">Public Instance methods</h3>
160
+
161
+ <div id="method-M000009" class="method-detail">
162
+ <a name="M000009"></a>
163
+
164
+ <div class="method-heading">
165
+ <a href="#M000009" class="method-signature">
166
+ <span class="method-name">activate_drb</span><span class="method-args">(uri = nil, allowed_hosts = ['localhost', '127.0.0.1', '::1'],
540
167
  ignore_collisions = false)</span>
168
+ </a>
169
+ </div>
170
+
171
+ <div class="method-description">
172
+ <p>
173
+ Will run <a href="Breakpoint.html">Breakpoint</a> in DRb mode. This will
174
+ spawn a server that can be attached to via the breakpoint-client command
175
+ whenever a breakpoint is executed. This is useful when you are debugging
176
+ CGI applications or other applications where you can&#8217;t access debug
177
+ sessions via the standard input and output of your application.
178
+ </p>
179
+ <p>
180
+ You can specify an URI where the DRb server will run at. This way you can
181
+ specify the port the server runs on. The default URI is
182
+ druby://localhost:42531.
183
+ </p>
184
+ <p>
185
+ Please note that breakpoints will be skipped silently in case the DRb
186
+ server can not spawned. (This can happen if the port is already used by
187
+ another instance of your application on CGI or another application.)
188
+ </p>
189
+ <p>
190
+ Also note that by default this will only allow access from localhost. You
191
+ can however specify a list of allowed hosts or nil (to allow access from
192
+ everywhere). But that will still not protect you from somebody reading the
193
+ data as it goes through the net.
194
+ </p>
195
+ <p>
196
+ A good approach for getting security and remote access is setting up an SSH
197
+ tunnel between the DRb service and the client. This is usually done like
198
+ this:
199
+ </p>
200
+ <p>
201
+ $ ssh -L20000:127.0.0.1:20000 -R10000:127.0.0.1:10000 example.com (This
202
+ will connect port 20000 at the client side to port 20000 at the server
203
+ side, and port 10000 at the server side to port 10000 at the client side.)
204
+ </p>
205
+ <p>
206
+ After that do this on the server side: (the code being debugged) <a
207
+ href="Breakpoint.html#M000009">Breakpoint.activate_drb</a>(&quot;druby://127.0.0.1:20000&quot;,
208
+ &quot;localhost&quot;)
209
+ </p>
210
+ <p>
211
+ And at the client side: ruby breakpoint_client.rb -c
212
+ druby://127.0.0.1:10000 -s druby://127.0.0.1:20000
213
+ </p>
214
+ <p>
215
+ Running through such a SSH proxy will also let you use breakpoint.rb in
216
+ case you are behind a firewall.
217
+ </p>
218
+ <p>
219
+ Detailed information about running DRb through firewalls is available at <a
220
+ href="http://www.rubygarden.org/ruby?DrbTutorial">www.rubygarden.org/ruby?DrbTutorial</a>
221
+ </p>
222
+ <h2>Security considerations</h2>
223
+ <p>
224
+ Usually you will be fine when using the default druby:// URI and the
225
+ default access control list. However, if you are sitting on a machine where
226
+ there are local users that you likely can not trust (this is the case for
227
+ example on most web hosts which have multiple users sitting on the same
228
+ physical machine) you will be better off by doing client/server
229
+ communication through a unix socket. This can be accomplished by calling
230
+ with a drbunix:/ style URI, e.g. <tt><a
231
+ href="Breakpoint.html#M000009">Breakpoint.activate_drb</a>(&#8216;drbunix:/tmp/breakpoint_server&#8217;)</tt>.
232
+ This will only work on Unix based platforms.
233
+ </p>
234
+ <p><a class="source-toggle" href="#"
235
+ onclick="toggleCode('M000009-source');return false;">[Source]</a></p>
236
+ <div class="method-source-code" id="M000009-source">
237
+ <pre>
238
+ <span class="ruby-comment cmt"># File lib/breakpoint.rb, line 398</span>
239
+ 398: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">activate_drb</span>(<span class="ruby-identifier">uri</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">allowed_hosts</span> = [<span class="ruby-value str">'localhost'</span>, <span class="ruby-value str">'127.0.0.1'</span>, <span class="ruby-value str">'::1'</span>],
240
+ 399: <span class="ruby-identifier">ignore_collisions</span> = <span class="ruby-keyword kw">false</span>)
241
+ 400:
242
+ 401: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">false</span> <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@use_drb</span>
243
+ 402:
244
+ 403: <span class="ruby-identifier">uri</span> <span class="ruby-operator">||=</span> <span class="ruby-value str">'druby://localhost:42531'</span>
245
+ 404:
246
+ 405: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">allowed_hosts</span> <span class="ruby-keyword kw">then</span>
247
+ 406: <span class="ruby-identifier">acl</span> = [<span class="ruby-value str">&quot;deny&quot;</span>, <span class="ruby-value str">&quot;all&quot;</span>]
248
+ 407:
249
+ 408: <span class="ruby-constant">Array</span>(<span class="ruby-identifier">allowed_hosts</span>).<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">host</span><span class="ruby-operator">|</span>
250
+ 409: <span class="ruby-identifier">acl</span> <span class="ruby-operator">+=</span> [<span class="ruby-value str">&quot;allow&quot;</span>, <span class="ruby-identifier">host</span>]
251
+ 410: <span class="ruby-keyword kw">end</span>
252
+ 411:
253
+ 412: <span class="ruby-constant">DRb</span>.<span class="ruby-identifier">install_acl</span>(<span class="ruby-constant">ACL</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">acl</span>))
254
+ 413: <span class="ruby-keyword kw">end</span>
255
+ 414:
256
+ 415: <span class="ruby-ivar">@use_drb</span> = <span class="ruby-keyword kw">true</span>
257
+ 416: <span class="ruby-ivar">@drb_service</span> = <span class="ruby-constant">DRbService</span>.<span class="ruby-identifier">new</span>
258
+ 417: <span class="ruby-identifier">did_collision</span> = <span class="ruby-keyword kw">false</span>
259
+ 418: <span class="ruby-keyword kw">begin</span>
260
+ 419: <span class="ruby-ivar">@service</span> = <span class="ruby-constant">DRb</span>.<span class="ruby-identifier">start_service</span>(<span class="ruby-identifier">uri</span>, <span class="ruby-ivar">@drb_service</span>)
261
+ 420: <span class="ruby-keyword kw">rescue</span> <span class="ruby-constant">Errno</span><span class="ruby-operator">::</span><span class="ruby-constant">EADDRINUSE</span>
262
+ 421: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">ignore_collisions</span> <span class="ruby-keyword kw">then</span>
263
+ 422: <span class="ruby-keyword kw">nil</span>
264
+ 423: <span class="ruby-keyword kw">else</span>
265
+ 424: <span class="ruby-comment cmt"># The port is already occupied by another
266
+ 425: <span class="ruby-comment cmt"># Breakpoint service. We will try to tell
267
+ 426: <span class="ruby-comment cmt"># the old service that we want its port.
268
+ 427: <span class="ruby-comment cmt"># It will then forward that request to the
269
+ 428: <span class="ruby-comment cmt"># user and retry.
270
+ 429: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">did_collision</span> <span class="ruby-keyword kw">then</span>
271
+ 430: <span class="ruby-constant">DRbObject</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">uri</span>).<span class="ruby-identifier">collision</span>
272
+ 431: <span class="ruby-identifier">did_collision</span> = <span class="ruby-keyword kw">true</span>
273
+ 432: <span class="ruby-keyword kw">end</span>
274
+ 433: <span class="ruby-identifier">sleep</span>(<span class="ruby-value">10</span>)
275
+ 434: <span class="ruby-keyword kw">retry</span>
276
+ 435: <span class="ruby-keyword kw">end</span>
277
+ 436: <span class="ruby-keyword kw">end</span>
278
+ 437:
279
+ 438: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">true</span>
280
+ 439: <span class="ruby-keyword kw">end</span>
281
+ </pre>
282
+ </div>
283
+ </div>
284
+ </div>
285
+
286
+ <div id="method-M000008" class="method-detail">
287
+ <a name="M000008"></a>
288
+
289
+ <div class="method-heading">
290
+ <a href="#M000008" class="method-signature">
291
+ <span class="method-name">assert</span><span class="method-args">(context = nil) {|| ...}</span>
292
+ </a>
293
+ </div>
294
+
295
+ <div class="method-description">
296
+ <p>
297
+ This asserts that the block evaluates to true. If it doesn&#8217;t evaluate
298
+ to true a breakpoint will automatically be created at that execution point.
299
+ </p>
300
+ <p>
301
+ You can disable assert checking in production code by setting
302
+ Breakpoint.optimize_asserts to true. (It will still be enabled when Ruby is
303
+ run via the -d argument.)
304
+ </p>
305
+ <p>
306
+ Example:
307
+ </p>
308
+ <pre>
309
+ person_name = &quot;Foobar&quot;
310
+ assert { not person_name.nil? }
311
+ </pre>
312
+ <p>
313
+ Note: If you want to use this method from an unit test, you will have to
314
+ call it by its full name, <a
315
+ href="Breakpoint.html#M000008">Breakpoint.assert</a>.
316
+ </p>
317
+ <p><a class="source-toggle" href="#"
318
+ onclick="toggleCode('M000008-source');return false;">[Source]</a></p>
319
+ <div class="method-source-code" id="M000008-source">
320
+ <pre>
321
+ <span class="ruby-comment cmt"># File lib/breakpoint.rb, line 268</span>
322
+ 268: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">assert</span>(<span class="ruby-identifier">context</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">condition</span>)
323
+ 269: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">if</span> <span class="ruby-constant">Breakpoint</span>.<span class="ruby-identifier">optimize_asserts</span> <span class="ruby-keyword kw">and</span> <span class="ruby-keyword kw">not</span> <span class="ruby-identifier">$DEBUG</span>
324
+ 270: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">yield</span>
325
+ 271:
326
+ 272: <span class="ruby-identifier">callstack</span> = <span class="ruby-identifier">caller</span>
327
+ 273: <span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">slice!</span>(<span class="ruby-value">0</span>, <span class="ruby-value">3</span>) <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">first</span>[<span class="ruby-value str">&quot;assert&quot;</span>]
328
+ 274: <span class="ruby-identifier">file</span>, <span class="ruby-identifier">line</span>, <span class="ruby-identifier">method</span> = <span class="ruby-operator">*</span><span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">first</span>.<span class="ruby-identifier">match</span>(<span class="ruby-regexp re">/^(.+?):(\d+)(?::in `(.*?)')?/</span>).<span class="ruby-identifier">captures</span>
329
+ 275:
330
+ 276: <span class="ruby-identifier">message</span> = <span class="ruby-node">&quot;Assert failed at #{file}:#{line}#{&quot; in `#{method}'&quot; if method}.&quot;</span>
331
+ 277:
332
+ 278: <span class="ruby-keyword kw">if</span> <span class="ruby-constant">Breakpoint</span>.<span class="ruby-identifier">asserts_cause_exceptions</span> <span class="ruby-keyword kw">and</span> <span class="ruby-keyword kw">not</span> <span class="ruby-identifier">$DEBUG</span> <span class="ruby-keyword kw">then</span>
333
+ 279: <span class="ruby-identifier">raise</span>(<span class="ruby-constant">Breakpoint</span><span class="ruby-operator">::</span><span class="ruby-constant">FailedAssertError</span>, <span class="ruby-identifier">message</span>)
334
+ 280: <span class="ruby-keyword kw">end</span>
335
+ 281:
336
+ 282: <span class="ruby-identifier">message</span> <span class="ruby-operator">+=</span> <span class="ruby-value str">&quot; Executing implicit breakpoint.&quot;</span>
337
+ 283:
338
+ 284: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">context</span> <span class="ruby-keyword kw">then</span>
339
+ 285: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">handle_breakpoint</span>(<span class="ruby-identifier">context</span>, <span class="ruby-identifier">message</span>, <span class="ruby-identifier">file</span>, <span class="ruby-identifier">line</span>)
340
+ 286: <span class="ruby-keyword kw">end</span>
341
+ 287:
342
+ 288: <span class="ruby-constant">Binding</span>.<span class="ruby-identifier">of_caller</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">context</span><span class="ruby-operator">|</span>
343
+ 289: <span class="ruby-identifier">handle_breakpoint</span>(<span class="ruby-identifier">context</span>, <span class="ruby-identifier">message</span>, <span class="ruby-identifier">file</span>, <span class="ruby-identifier">line</span>)
344
+ 290: <span class="ruby-keyword kw">end</span>
345
+ 291: <span class="ruby-keyword kw">end</span>
346
+ </pre>
347
+ </div>
348
+ </div>
349
+ </div>
350
+
351
+ <div id="method-M000007" class="method-detail">
352
+ <a name="M000007"></a>
353
+
354
+ <div class="method-heading">
355
+ <a href="#M000007" class="method-signature">
356
+ <span class="method-name">breakpoint</span><span class="method-args">(id = nil, context = nil, &amp;block)</span>
357
+ </a>
358
+ </div>
359
+
360
+ <div class="method-description">
361
+ <p>
362
+ This will pop up an interactive ruby session at a pre-defined break point
363
+ in a Ruby application. In this session you can examine the environment of
364
+ the break point.
365
+ </p>
366
+ <p>
367
+ You can get a list of variables in the context using local_variables via
368
+ <tt>local_variables</tt>. You can then examine their values by typing their
369
+ names.
370
+ </p>
371
+ <p>
372
+ You can have a look at the call stack via <tt>caller</tt>.
373
+ </p>
374
+ <p>
375
+ The source code around the location where the breakpoint was executed can
376
+ be examined via <tt>source_lines</tt>. Its argument specifies how much
377
+ lines of context to display. The default amount of context is 5 lines. Note
378
+ that the call to <tt>source_lines</tt> can raise an exception when it
379
+ isn&#8217;t able to read in the source code.
380
+ </p>
381
+ <p>
382
+ breakpoints can also return a value. They will execute a supplied block for
383
+ getting a default return value. A custom value can be returned from the
384
+ session by doing <tt>throw(:debug_return, value)</tt>.
385
+ </p>
386
+ <p>
387
+ You can also give names to break points which will be used in the message
388
+ that is displayed upon execution of them.
389
+ </p>
390
+ <p>
391
+ Here&#8217;s a sample of how breakpoints should be placed:
392
+ </p>
393
+ <pre>
394
+ class Person
395
+ def initialize(name, age)
396
+ @name, @age = name, age
397
+ breakpoint(&quot;Person#initialize&quot;)
398
+ end
399
+
400
+ attr_reader :age
401
+ def name
402
+ breakpoint(&quot;Person#name&quot;) { @name }
403
+ end
404
+ end
405
+
406
+ person = Person.new(&quot;Random Person&quot;, 23)
407
+ puts &quot;Name: #{person.name}&quot;
408
+ </pre>
409
+ <p>
410
+ And here is a sample debug session:
411
+ </p>
412
+ <pre>
413
+ Executing break point &quot;Person#initialize&quot; at file.rb:4 in `initialize'
414
+ irb(#&lt;Person:0x292fbe8&gt;):001:0&gt; local_variables
415
+ =&gt; [&quot;name&quot;, &quot;age&quot;, &quot;_&quot;, &quot;__&quot;]
416
+ irb(#&lt;Person:0x292fbe8&gt;):002:0&gt; [name, age]
417
+ =&gt; [&quot;Random Person&quot;, 23]
418
+ irb(#&lt;Person:0x292fbe8&gt;):003:0&gt; [@name, @age]
419
+ =&gt; [&quot;Random Person&quot;, 23]
420
+ irb(#&lt;Person:0x292fbe8&gt;):004:0&gt; self
421
+ =&gt; #&lt;Person:0x292fbe8 @age=23, @name=&quot;Random Person&quot;&gt;
422
+ irb(#&lt;Person:0x292fbe8&gt;):005:0&gt; @age += 1; self
423
+ =&gt; #&lt;Person:0x292fbe8 @age=24, @name=&quot;Random Person&quot;&gt;
424
+ irb(#&lt;Person:0x292fbe8&gt;):006:0&gt; exit
425
+ Executing break point &quot;Person#name&quot; at file.rb:9 in `name'
426
+ irb(#&lt;Person:0x292fbe8&gt;):001:0&gt; throw(:debug_return, &quot;Overriden name&quot;)
427
+ Name: Overriden name
428
+ </pre>
429
+ <p>
430
+ <a href="Breakpoint.html">Breakpoint</a> sessions will automatically have a
431
+ few convenience methods available. See <a
432
+ href="Breakpoint/CommandBundle.html">Breakpoint::CommandBundle</a> for a
433
+ list of them.
434
+ </p>
435
+ <p>
436
+ Breakpoints can also be used remotely over sockets. This is implemented by
437
+ running part of the IRB session in the application and part of it in a
438
+ special client. You have to call <a
439
+ href="Breakpoint.html#M000009">Breakpoint.activate_drb</a> to enable
440
+ support for remote breakpoints and then run breakpoint_client.rb which is
441
+ distributed with this library. See the documentation of <a
442
+ href="Breakpoint.html#M000009">Breakpoint.activate_drb</a> for details.
443
+ </p>
444
+ <p>
445
+ Please use breakpoint() instead of <a
446
+ href="Breakpoint.html#M000007">Breakpoint.breakpoint</a>(). If you use <a
447
+ href="Breakpoint.html#M000007">Breakpoint.breakpoint</a>() you might get a
448
+ shell with a wrong self context meaning that you will not be able to access
449
+ instance variables, call methods on the object where you are breakpointing
450
+ and so on. You will however still be able to access local variables.
451
+ </p>
452
+ <p>
453
+ The former is believed to be caused by a bug in Ruby and it has been
454
+ reported to ruby-core: <a
455
+ href="http://www.ruby-forum.com/topic/67255">www.ruby-forum.com/topic/67255</a>
456
+ </p>
457
+ <p><a class="source-toggle" href="#"
458
+ onclick="toggleCode('M000007-source');return false;">[Source]</a></p>
459
+ <div class="method-source-code" id="M000007-source">
460
+ <pre>
461
+ <span class="ruby-comment cmt"># File lib/breakpoint.rb, line 120</span>
462
+ 120: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">breakpoint</span>(<span class="ruby-identifier">id</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">context</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
463
+ 121: <span class="ruby-identifier">callstack</span> = <span class="ruby-identifier">caller</span>
464
+ 122: <span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">slice!</span>(<span class="ruby-value">0</span>, <span class="ruby-value">3</span>) <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">first</span>[<span class="ruby-value str">&quot;breakpoint&quot;</span>]
465
+ 123: <span class="ruby-identifier">file</span>, <span class="ruby-identifier">line</span>, <span class="ruby-identifier">method</span> = <span class="ruby-operator">*</span><span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">first</span>.<span class="ruby-identifier">match</span>(<span class="ruby-regexp re">/^(.+?):(\d+)(?::in `(.*?)')?/</span>).<span class="ruby-identifier">captures</span>
466
+ 124:
467
+ 125: <span class="ruby-identifier">message</span> = <span class="ruby-value str">&quot;Executing break point &quot;</span> <span class="ruby-operator">+</span> (<span class="ruby-identifier">id</span> <span class="ruby-value">? </span><span class="ruby-node">&quot;#{id.inspect} &quot;</span> <span class="ruby-operator">:</span> <span class="ruby-value str">&quot;&quot;</span>) <span class="ruby-operator">+</span>
468
+ 126: <span class="ruby-node">&quot;at #{file}:#{line}&quot;</span> <span class="ruby-operator">+</span> (<span class="ruby-identifier">method</span> <span class="ruby-value">? </span><span class="ruby-node">&quot; in `#{method}'&quot;</span> <span class="ruby-operator">:</span> <span class="ruby-value str">&quot;&quot;</span>)
469
+ 127:
470
+ 128: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">context</span> <span class="ruby-keyword kw">then</span>
471
+ 129: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">handle_breakpoint</span>(<span class="ruby-identifier">context</span>, <span class="ruby-identifier">message</span>, <span class="ruby-identifier">file</span>, <span class="ruby-identifier">line</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
472
+ 130: <span class="ruby-keyword kw">end</span>
473
+ 131:
474
+ 132: <span class="ruby-constant">Binding</span>.<span class="ruby-identifier">of_caller</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">binding_context</span><span class="ruby-operator">|</span>
475
+ 133: <span class="ruby-identifier">handle_breakpoint</span>(<span class="ruby-identifier">binding_context</span>, <span class="ruby-identifier">message</span>, <span class="ruby-identifier">file</span>, <span class="ruby-identifier">line</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
476
+ 134: <span class="ruby-keyword kw">end</span>
477
+ 135: <span class="ruby-keyword kw">end</span>
478
+ </pre>
479
+ </div>
480
+ </div>
481
+ </div>
482
+
483
+ <div id="method-M000010" class="method-detail">
484
+ <a name="M000010"></a>
485
+
486
+ <div class="method-heading">
487
+ <a href="#M000010" class="method-signature">
488
+ <span class="method-name">deactivate_drb</span><span class="method-args">()</span>
489
+ </a>
490
+ </div>
491
+
492
+ <div class="method-description">
493
+ <p>
494
+ Deactivates a running <a href="Breakpoint.html">Breakpoint</a> service.
495
+ </p>
496
+ <p><a class="source-toggle" href="#"
497
+ onclick="toggleCode('M000010-source');return false;">[Source]</a></p>
498
+ <div class="method-source-code" id="M000010-source">
499
+ <pre>
500
+ <span class="ruby-comment cmt"># File lib/breakpoint.rb, line 442</span>
501
+ 442: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">deactivate_drb</span>
502
+ 443: <span class="ruby-constant">Thread</span>.<span class="ruby-identifier">exclusive</span> <span class="ruby-keyword kw">do</span>
503
+ 444: <span class="ruby-ivar">@service</span>.<span class="ruby-identifier">stop_service</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-ivar">@service</span>.<span class="ruby-identifier">nil?</span>
504
+ 445: <span class="ruby-ivar">@service</span> = <span class="ruby-keyword kw">nil</span>
505
+ 446: <span class="ruby-ivar">@use_drb</span> = <span class="ruby-keyword kw">false</span>
506
+ 447: <span class="ruby-ivar">@drb_service</span> = <span class="ruby-keyword kw">nil</span>
507
+ 448: <span class="ruby-keyword kw">end</span>
508
+ 449: <span class="ruby-keyword kw">end</span>
509
+ </pre>
510
+ </div>
511
+ </div>
512
+ </div>
513
+
514
+ <div id="method-M000011" class="method-detail">
515
+ <a name="M000011"></a>
516
+
517
+ <div class="method-heading">
518
+ <a href="#M000011" class="method-signature">
519
+ <span class="method-name">use_drb?</span><span class="method-args">()</span>
520
+ </a>
521
+ </div>
522
+
523
+ <div class="method-description">
524
+ <p>
525
+ Returns true when Breakpoints are used over DRb. <a
526
+ href="Breakpoint.html#M000009">Breakpoint.activate_drb</a> causes this to
527
+ be true.
528
+ </p>
529
+ <p><a class="source-toggle" href="#"
530
+ onclick="toggleCode('M000011-source');return false;">[Source]</a></p>
531
+ <div class="method-source-code" id="M000011-source">
532
+ <pre>
533
+ <span class="ruby-comment cmt"># File lib/breakpoint.rb, line 453</span>
534
+ 453: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">use_drb?</span>
535
+ 454: <span class="ruby-ivar">@use_drb</span> <span class="ruby-operator">==</span> <span class="ruby-keyword kw">true</span>
536
+ 455: <span class="ruby-keyword kw">end</span>
537
+ </pre>
538
+ </div>
539
+ </div>
540
+ </div>
541
+
542
+
543
+ </div>
544
+
545
+
546
+ </div>
547
+
548
+
549
+ <div id="validator-badges">
550
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
551
+ </div>
552
+
553
+ </body>
541
554
  </html>