ruby-breakpoint 0.5.0 → 0.5.1

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.
@@ -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>