ionian 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b86e85b6f1eac510ccf6b43d701e0d1ff6fc8c90
4
- data.tar.gz: 322d2d6bd87e89d79a357017bb561192b101d38d
3
+ metadata.gz: 56bba77a98b933d714a09236d6d1caf7a19826e5
4
+ data.tar.gz: b480aa6ceb1ff16602dcdf214cc9ca42c67f0509
5
5
  SHA512:
6
- metadata.gz: a2b555e4a9d5ad52f3a8ad7720c570d0f2710e246bff41ab5a7fe49465a3b3bc00b508a3c2ee2b017cd8049cec1ef13f182c668a631eef5cbd0dd0d022f08831
7
- data.tar.gz: 1e556b489c9513e82b364774756bdff1247cedb6266a82eaa3f3c3611460fc6c76fca675a5f5f6aa5e11d55a768e2234bd624f2c6f0ad252c2ce791c404d1579
6
+ metadata.gz: 1ecbcd365657210fcbafbb95834320556905f2065a730baa2c0655c5a7e90f08ce0dc5c3538b94aaafb2940c92c3ba74f72ac8c2b1192fa1268b52d3cd8ce4bd
7
+ data.tar.gz: bbc718243843149e4fe45b49389ebc99c9209c5b48c0c8509b634b28a0354121104027523a263fb4e57704be2d8f1196e02c5a37c707289e1d6e7206d9aaad25
data/doc/Ionian/IO.html CHANGED
@@ -69,9 +69,13 @@
69
69
 
70
70
  <li ><a href="#method-c-extended">::extended</a>
71
71
 
72
+ <li ><a href="#method-i-expression">#expression</a>
73
+
74
+ <li ><a href="#method-i-expression-3D">#expression=</a>
75
+
72
76
  <li ><a href="#method-i-initialize_ionian">#initialize_ionian</a>
73
77
 
74
- <li ><a href="#method-i-match">#match</a>
78
+ <li ><a href="#method-i-on_match">#on_match</a>
75
79
 
76
80
  <li ><a href="#method-i-purge">#purge</a>
77
81
 
@@ -97,7 +101,7 @@
97
101
  <section class="description">
98
102
 
99
103
  <p>A mixin for <a href="IO.html">IO</a> objects that allows regular expression
100
- matching and convenient notification of data in the buffer.</p>
104
+ matching and convenient notification of received data.</p>
101
105
 
102
106
  <p>This module was designed to be EXTENDED by instantiated objects that
103
107
  implement the standard library <a href="IO.html">IO</a> class.
@@ -187,10 +191,10 @@ timing out. See standard library IO::select.</p>
187
191
  </header>
188
192
 
189
193
 
190
- <div id="method-i-initialize_ionian" class="method-detail ">
194
+ <div id="method-i-expression" class="method-detail ">
191
195
 
192
196
  <div class="method-heading">
193
- <span class="method-name">initialize_ionian</span><span
197
+ <span class="method-name">expression</span><span
194
198
  class="method-args">()</span>
195
199
 
196
200
  <span class="method-click-advice">click to toggle source</span>
@@ -200,19 +204,16 @@ timing out. See standard library IO::select.</p>
200
204
 
201
205
  <div class="method-description">
202
206
 
203
- <p>Initialize the <a href="../Ionian.html">Ionian</a> instance variables. This
204
- is called automatically if extend is called on an object.</p>
207
+ <p>Returns the regular expression used for <a
208
+ href="IO.html#method-i-read_match">read_match</a>.</p>
205
209
 
206
210
 
207
211
 
208
212
 
209
- <div class="method-source-code" id="initialize_ionian-source">
210
- <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 20</span>
211
- <span class="ruby-keyword">def</span> <span class="ruby-identifier">initialize_ionian</span>
212
- <span class="ruby-ivar">@ionian_listeners</span> = []
213
- <span class="ruby-ivar">@ionian_buf</span> = <span class="ruby-string">&#39;&#39;</span>
214
- <span class="ruby-ivar">@ionian_expression</span> = <span class="ruby-regexp">/(.*?)\n/</span>
215
- <span class="ruby-ivar">@ionian_timeout</span> = <span class="ruby-value">1</span>
213
+ <div class="method-source-code" id="expression-source">
214
+ <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 30</span>
215
+ <span class="ruby-keyword">def</span> <span class="ruby-identifier">expression</span>
216
+ <span class="ruby-ivar">@ionian_expression</span>
216
217
  <span class="ruby-keyword">end</span></pre>
217
218
  </div>
218
219
 
@@ -224,11 +225,11 @@ is called automatically if extend is called on an object.</p>
224
225
  </div>
225
226
 
226
227
 
227
- <div id="method-i-match" class="method-detail ">
228
+ <div id="method-i-expression-3D" class="method-detail ">
228
229
 
229
230
  <div class="method-heading">
230
- <span class="method-name">match</span><span
231
- class="method-args">(expression)</span>
231
+ <span class="method-name">expression=</span><span
232
+ class="method-args">(exp)</span>
232
233
 
233
234
  <span class="method-click-advice">click to toggle source</span>
234
235
 
@@ -246,11 +247,11 @@ href=":parameter">match</a>.</p>
246
247
 
247
248
 
248
249
 
249
- <div class="method-source-code" id="match-source">
250
- <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 33</span>
251
- <span class="ruby-keyword">def</span> <span class="ruby-identifier">match</span>(<span class="ruby-identifier">expression</span>)
252
- <span class="ruby-ivar">@ionian_expression</span> = <span class="ruby-identifier">expression</span>
253
- <span class="ruby-ivar">@ionian_expression</span> = <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">new</span> <span class="ruby-node">&quot;(.*?)#{expression}&quot;</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">expression</span>.<span class="ruby-identifier">is_a?</span> <span class="ruby-constant">String</span>
250
+ <div class="method-source-code" id="expression-3D-source">
251
+ <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 40</span>
252
+ <span class="ruby-keyword">def</span> <span class="ruby-identifier">expression=</span>(<span class="ruby-identifier">exp</span>)
253
+ <span class="ruby-ivar">@ionian_expression</span> = <span class="ruby-identifier">exp</span>
254
+ <span class="ruby-ivar">@ionian_expression</span> = <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">new</span> <span class="ruby-node">&quot;(.*?)#{expression}&quot;</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">exp</span>.<span class="ruby-identifier">is_a?</span> <span class="ruby-constant">String</span>
254
255
  <span class="ruby-keyword">end</span></pre>
255
256
  </div>
256
257
 
@@ -262,6 +263,73 @@ href=":parameter">match</a>.</p>
262
263
  </div>
263
264
 
264
265
 
266
+ <div id="method-i-initialize_ionian" class="method-detail ">
267
+
268
+ <div class="method-heading">
269
+ <span class="method-name">initialize_ionian</span><span
270
+ class="method-args">()</span>
271
+
272
+ <span class="method-click-advice">click to toggle source</span>
273
+
274
+ </div>
275
+
276
+
277
+ <div class="method-description">
278
+
279
+ <p>Initialize the <a href="../Ionian.html">Ionian</a> instance variables. This
280
+ is called automatically if extend is called on an object.</p>
281
+
282
+
283
+
284
+
285
+ <div class="method-source-code" id="initialize_ionian-source">
286
+ <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 20</span>
287
+ <span class="ruby-keyword">def</span> <span class="ruby-identifier">initialize_ionian</span>
288
+ <span class="ruby-ivar">@ionian_listeners</span> = []
289
+ <span class="ruby-ivar">@ionian_buf</span> = <span class="ruby-string">&#39;&#39;</span>
290
+ <span class="ruby-ivar">@ionian_expression</span> = <span class="ruby-regexp">/(.*?)\n/</span>
291
+ <span class="ruby-ivar">@ionian_timeout</span> = <span class="ruby-keyword">nil</span>
292
+ <span class="ruby-ivar">@ionian_skip_select</span> = <span class="ruby-keyword">false</span>
293
+ <span class="ruby-ivar">@ionian_build_methods</span> = <span class="ruby-keyword">true</span>
294
+ <span class="ruby-keyword">end</span></pre>
295
+ </div>
296
+
297
+ </div>
298
+
299
+
300
+
301
+
302
+ </div>
303
+
304
+
305
+ <div id="method-i-on_match" class="method-detail method-alias">
306
+
307
+ <div class="method-heading">
308
+ <span class="method-name">on_match</span><span
309
+ class="method-args">(&block)</span>
310
+
311
+ </div>
312
+
313
+
314
+ <div class="method-description">
315
+
316
+
317
+
318
+
319
+
320
+
321
+ </div>
322
+
323
+
324
+
325
+
326
+ <div class="aliases">
327
+ Alias for: <a href="IO.html#method-i-register_observer">register_observer</a>
328
+ </div>
329
+
330
+ </div>
331
+
332
+
265
333
  <div id="method-i-purge" class="method-detail ">
266
334
 
267
335
  <div class="method-heading">
@@ -275,14 +343,21 @@ href=":parameter">match</a>.</p>
275
343
 
276
344
  <div class="method-description">
277
345
 
278
- <p>Erase the data in Ionian&#39;s buffer.</p>
346
+ <p>Erase the data in the <a href="IO.html">IO</a> and <a
347
+ href="../Ionian.html">Ionian</a> buffers. This is typically handled
348
+ automatically.</p>
279
349
 
280
350
 
281
351
 
282
352
 
283
353
  <div class="method-source-code" id="purge-source">
284
- <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 89</span>
354
+ <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 128</span>
285
355
  <span class="ruby-keyword">def</span> <span class="ruby-identifier">purge</span>
356
+ <span class="ruby-comment"># Erase IO buffer.</span>
357
+ <span class="ruby-keyword">while</span> <span class="ruby-operator">::</span><span class="ruby-constant">IO</span>.<span class="ruby-identifier">select</span> [<span class="ruby-keyword">self</span>], <span class="ruby-keyword">nil</span>, <span class="ruby-keyword">nil</span>, <span class="ruby-value">0</span>
358
+ <span class="ruby-identifier">readpartial</span>(<span class="ruby-value">0xFFFF</span>)
359
+ <span class="ruby-keyword">end</span>
360
+
286
361
  <span class="ruby-ivar">@ionian_buf</span> = <span class="ruby-string">&#39;&#39;</span>
287
362
  <span class="ruby-keyword">end</span></pre>
288
363
  </div>
@@ -322,33 +397,57 @@ with match.pre_match.</p>
322
397
 
323
398
  <p>Data at the end of the buffer that is not matched can be accessed in the
324
399
  last match with match.post_match. This data remains in the buffer for the
325
- next <a href="IO.html#method-i-read_match">#read_match</a> cycle. This is
400
+ next <a href="IO.html#method-i-read_match">read_match</a> cycle. This is
326
401
  helpful for protocols like RS232 that do not have packet boundries.</p>
327
402
 
328
403
  <p>kvargs:</p>
329
404
 
330
- <pre>Timeout: Timeout in seconds IO::select will block.</pre>
405
+ <pre>timeout: Timeout in seconds IO::select will block.
406
+ skip_select: Skip over the IO::select statement. Use if you
407
+ are calling IO::select ahead of this method.
408
+ build_methods: Build method accessors from named captures.
409
+ Enabled by default.</pre>
331
410
 
332
411
 
333
412
 
334
413
 
335
414
  <div class="method-source-code" id="read_match-source">
336
- <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 57</span>
337
- <span class="ruby-keyword">def</span> <span class="ruby-identifier">read_match</span>(<span class="ruby-operator">**</span><span class="ruby-identifier">kvargs</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
338
- <span class="ruby-identifier">timeout</span> = <span class="ruby-identifier">kvargs</span>.<span class="ruby-identifier">fetch</span> <span class="ruby-value">:timeout</span>, <span class="ruby-ivar">@ionian_timeout</span>
339
-
340
- <span class="ruby-keyword">return</span> <span class="ruby-keyword">nil</span> <span class="ruby-keyword">unless</span> <span class="ruby-constant">IO</span>.<span class="ruby-identifier">select</span> [<span class="ruby-keyword">self</span>], <span class="ruby-keyword">nil</span>, <span class="ruby-keyword">nil</span>, <span class="ruby-identifier">timeout</span>
341
- <span class="ruby-ivar">@ionian_buf</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">read_partial</span> <span class="ruby-value">0xFFFF</span>
342
-
343
- <span class="ruby-ivar">@matches</span> = []
344
-
345
- <span class="ruby-keyword">while</span> <span class="ruby-ivar">@ionian_buf</span> <span class="ruby-operator">=~</span> <span class="ruby-ivar">@ionian_expression</span>
346
- <span class="ruby-ivar">@matches</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">$~</span> <span class="ruby-comment"># Match data.</span>
347
- <span class="ruby-keyword">yield</span> <span class="ruby-identifier">$~</span>
348
- <span class="ruby-keyword">end</span>
349
-
350
- <span class="ruby-ivar">@ionian_buf</span> = <span class="ruby-node">$&#39;</span> <span class="ruby-comment"># Leave post match data in the buffer.</span>
351
- <span class="ruby-ivar">@matches</span>
415
+ <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 68</span>
416
+ <span class="ruby-keyword">def</span> <span class="ruby-identifier">read_match</span>(<span class="ruby-operator">**</span><span class="ruby-identifier">kvargs</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
417
+ <span class="ruby-identifier">timeout</span> = <span class="ruby-identifier">kvargs</span>.<span class="ruby-identifier">fetch</span> <span class="ruby-value">:timeout</span>, <span class="ruby-ivar">@ionian_timeout</span>
418
+ <span class="ruby-identifier">skip_select</span> = <span class="ruby-identifier">kvargs</span>.<span class="ruby-identifier">fetch</span> <span class="ruby-value">:skip_select</span>, <span class="ruby-ivar">@ionian_skip_select</span>
419
+ <span class="ruby-identifier">build_methods</span> = <span class="ruby-identifier">kvargs</span>.<span class="ruby-identifier">fetch</span> <span class="ruby-value">:build_methods</span>, <span class="ruby-ivar">@ionian_build_methods</span>
420
+
421
+ <span class="ruby-keyword">unless</span> <span class="ruby-identifier">skip_select</span>
422
+ <span class="ruby-keyword">return</span> <span class="ruby-keyword">nil</span> <span class="ruby-keyword">unless</span> <span class="ruby-operator">::</span><span class="ruby-constant">IO</span>.<span class="ruby-identifier">select</span> [<span class="ruby-keyword">self</span>], <span class="ruby-keyword">nil</span>, <span class="ruby-keyword">nil</span>, <span class="ruby-identifier">timeout</span>
423
+ <span class="ruby-keyword">end</span>
424
+
425
+ <span class="ruby-comment"># Read data from the IO buffer until it&#39;s empty.</span>
426
+ <span class="ruby-identifier">loop</span> <span class="ruby-keyword">do</span>
427
+ <span class="ruby-ivar">@ionian_buf</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">readpartial</span>(<span class="ruby-value">0xFFFF</span>)
428
+ <span class="ruby-keyword">break</span> <span class="ruby-keyword">unless</span> <span class="ruby-operator">::</span><span class="ruby-constant">IO</span>.<span class="ruby-identifier">select</span> [<span class="ruby-keyword">self</span>], <span class="ruby-keyword">nil</span>, <span class="ruby-keyword">nil</span>, <span class="ruby-value">0</span>
429
+ <span class="ruby-keyword">end</span>
430
+
431
+ <span class="ruby-ivar">@matches</span> = []
432
+
433
+ <span class="ruby-keyword">while</span> <span class="ruby-ivar">@ionian_buf</span> <span class="ruby-operator">=~</span> <span class="ruby-ivar">@ionian_expression</span>
434
+ <span class="ruby-ivar">@matches</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">$~</span> <span class="ruby-comment"># Match data.</span>
435
+ <span class="ruby-keyword">yield</span> <span class="ruby-identifier">$~</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">block_given?</span>
436
+ <span class="ruby-ivar">@ionian_buf</span> = <span class="ruby-node">$&#39;</span> <span class="ruby-comment"># Leave post match data in the buffer.</span>
437
+ <span class="ruby-keyword">end</span>
438
+
439
+ <span class="ruby-comment"># Convert match parameters to methods.</span>
440
+ <span class="ruby-keyword">if</span> <span class="ruby-identifier">build_methods</span>
441
+ <span class="ruby-ivar">@matches</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">match</span><span class="ruby-operator">|</span>
442
+ <span class="ruby-identifier">match</span>.<span class="ruby-identifier">names</span>
443
+ .<span class="ruby-identifier">map</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">name</span><span class="ruby-operator">|</span> <span class="ruby-identifier">name</span>.<span class="ruby-identifier">to_sym</span>}
444
+ .<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">symbol</span><span class="ruby-operator">|</span> <span class="ruby-identifier">match</span>.<span class="ruby-identifier">singleton_class</span>
445
+ .<span class="ruby-identifier">send</span>(<span class="ruby-value">:define_method</span>, <span class="ruby-identifier">symbol</span>) { <span class="ruby-identifier">match</span>[<span class="ruby-identifier">symbol</span>] } <span class="ruby-keyword">unless</span> <span class="ruby-identifier">match</span>.<span class="ruby-identifier">respond_to?</span> <span class="ruby-identifier">symbol</span>
446
+ }
447
+ <span class="ruby-keyword">end</span>
448
+ <span class="ruby-keyword">end</span>
449
+
450
+ <span class="ruby-ivar">@matches</span>
352
451
  <span class="ruby-keyword">end</span></pre>
353
452
  </div>
354
453
 
@@ -383,7 +482,7 @@ ionian_socket.register_observer {…}</p>
383
482
 
384
483
 
385
484
  <div class="method-source-code" id="register_observer-source">
386
- <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 97</span>
485
+ <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 141</span>
387
486
  <span class="ruby-keyword">def</span> <span class="ruby-identifier">register_observer</span>(<span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
388
487
  <span class="ruby-ivar">@ionian_listeners</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">block</span> <span class="ruby-keyword">unless</span> <span class="ruby-ivar">@ionian_listeners</span>.<span class="ruby-identifier">include?</span> <span class="ruby-identifier">block</span>
389
488
  <span class="ruby-identifier">block</span>
@@ -393,6 +492,10 @@ ionian_socket.register_observer {…}</p>
393
492
  </div>
394
493
 
395
494
 
495
+ <div class="aliases">
496
+ Also aliased as: <a href="IO.html#method-i-on_match">on_match</a>
497
+ </div>
498
+
396
499
 
397
500
 
398
501
  </div>
@@ -402,7 +505,7 @@ ionian_socket.register_observer {…}</p>
402
505
 
403
506
  <div class="method-heading">
404
507
  <span class="method-name">run_match</span><span
405
- class="method-args">(**kvargs) { |matches| ... }</span>
508
+ class="method-args">(**kvargs)</span>
406
509
 
407
510
  <span class="method-click-advice">click to toggle source</span>
408
511
 
@@ -411,21 +514,27 @@ ionian_socket.register_observer {…}</p>
411
514
 
412
515
  <div class="method-description">
413
516
 
414
- <p>Start a thread that checks for data and notifies listeners. Passes kvargs
415
- to <a href="IO.html#method-i-read_match">read_match</a>. This method SHOULD
416
- NOT be used if <a href="IO.html#method-i-read_match">read_match</a> is
417
- used.</p>
517
+ <p>Start a thread that checks for data and notifies listeners (do |match,
518
+ socket|). Passes kvargs to <a
519
+ href="IO.html#method-i-read_match">read_match</a>. This method SHOULD NOT
520
+ be used if <a href="IO.html#method-i-read_match">read_match</a> is used.</p>
418
521
 
419
522
 
420
523
 
421
524
 
422
525
  <div class="method-source-code" id="run_match-source">
423
- <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 77</span>
526
+ <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 109</span>
424
527
  <span class="ruby-keyword">def</span> <span class="ruby-identifier">run_match</span>(<span class="ruby-operator">**</span><span class="ruby-identifier">kvargs</span>)
425
528
  <span class="ruby-ivar">@match_listener</span> <span class="ruby-operator">||=</span> <span class="ruby-constant">Thread</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword">do</span>
426
- <span class="ruby-keyword">while</span> <span class="ruby-keyword">not</span> <span class="ruby-identifier">closed?</span> <span class="ruby-keyword">do</span>
427
- <span class="ruby-identifier">matches</span> = <span class="ruby-identifier">read_match</span> <span class="ruby-identifier">kvargs</span>
428
- <span class="ruby-ivar">@ionian_listeners</span>.<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">listener</span><span class="ruby-operator">|</span> <span class="ruby-keyword">yield</span> <span class="ruby-identifier">matches</span>} <span class="ruby-keyword">if</span> <span class="ruby-identifier">matches</span>
529
+ <span class="ruby-keyword">begin</span>
530
+ <span class="ruby-keyword">while</span> <span class="ruby-keyword">not</span> <span class="ruby-identifier">closed?</span> <span class="ruby-keyword">do</span>
531
+ <span class="ruby-identifier">matches</span> = <span class="ruby-identifier">read_match</span> <span class="ruby-identifier">kvargs</span>
532
+ <span class="ruby-identifier">matches</span>.<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">match</span><span class="ruby-operator">|</span>
533
+ <span class="ruby-ivar">@ionian_listeners</span>.<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">listener</span><span class="ruby-operator">|</span> <span class="ruby-identifier">listener</span>.<span class="ruby-identifier">call</span> <span class="ruby-identifier">match</span>, <span class="ruby-keyword">self</span>}
534
+ } <span class="ruby-keyword">if</span> <span class="ruby-identifier">matches</span>
535
+ <span class="ruby-keyword">end</span>
536
+ <span class="ruby-keyword">rescue</span> <span class="ruby-constant">EOFError</span>
537
+ <span class="ruby-keyword">rescue</span> <span class="ruby-constant">IOError</span>
429
538
  <span class="ruby-keyword">end</span>
430
539
 
431
540
  <span class="ruby-ivar">@match_listener</span> = <span class="ruby-keyword">nil</span>
@@ -460,7 +569,7 @@ used.</p>
460
569
 
461
570
 
462
571
  <div class="method-source-code" id="unregister_observer-source">
463
- <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 103</span>
572
+ <pre><span class="ruby-comment"># File lib/ionian/io.rb, line 149</span>
464
573
  <span class="ruby-keyword">def</span> <span class="ruby-identifier">unregister_observer</span>(<span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
465
574
  <span class="ruby-ivar">@ionian_listeners</span>.<span class="ruby-identifier">delete_if</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">o</span><span class="ruby-operator">|</span> <span class="ruby-identifier">o</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">block</span>}
466
575
  <span class="ruby-identifier">block</span>
data/doc/Ionian.html CHANGED
@@ -72,6 +72,11 @@
72
72
 
73
73
  <section class="description">
74
74
 
75
+ <p>A library to simplify interaction with <a href="Ionian/IO.html">IO</a>
76
+ streams. This includes network sockets, file sockets, and serial streams
77
+ like the console and RS232. Features regular expression matching and
78
+ notification of received data.</p>
79
+
75
80
  </section>
76
81
 
77
82
 
data/doc/created.rid CHANGED
@@ -1,3 +1,3 @@
1
- Wed, 13 Nov 2013 18:38:14 -0800
2
- lib/ionian.rb Wed, 13 Nov 2013 18:29:31 -0800
3
- lib/ionian/io.rb Wed, 13 Nov 2013 18:31:32 -0800
1
+ Thu, 14 Nov 2013 20:06:47 -0800
2
+ lib/ionian.rb Thu, 14 Nov 2013 20:05:18 -0800
3
+ lib/ionian/io.rb Thu, 14 Nov 2013 20:03:31 -0800
@@ -1 +1 @@
1
- var search_data = {"index":{"searchIndex":["ionian","io","extended()","initialize_ionian()","match()","purge()","read_match()","register_observer()","run_match()","unregister_observer()"],"longSearchIndex":["ionian","ionian::io","ionian::io::extended()","ionian::io#initialize_ionian()","ionian::io#match()","ionian::io#purge()","ionian::io#read_match()","ionian::io#register_observer()","ionian::io#run_match()","ionian::io#unregister_observer()"],"info":[["Ionian","","Ionian.html","",""],["Ionian::IO","","Ionian/IO.html","","<p>A mixin for IO objects that allows regular expression matching and\nconvenient notification of data in …\n"],["extended","Ionian::IO","Ionian/IO.html#method-c-extended","(obj)","<p>Called automaticallly when the object is extended with #extend.\n"],["initialize_ionian","Ionian::IO","Ionian/IO.html#method-i-initialize_ionian","()","<p>Initialize the Ionian instance variables. This is called automatically if\n#extend is called on an object. …\n"],["match","Ionian::IO","Ionian/IO.html#method-i-match","(expression)","<p>Set the expression to match against the read buffer. Can be a regular\nexpression specifying capture groups, …\n"],["purge","Ionian::IO","Ionian/IO.html#method-i-purge","()","<p>Erase the data in Ionian&#39;s buffer.\n"],["read_match","Ionian::IO","Ionian/IO.html#method-i-read_match","(**kvargs, &block)","<p>Read matched data from the buffer. This method SHOULD NOT be used if\n#run_match is used.\n<p>Passes matches …\n"],["register_observer","Ionian::IO","Ionian/IO.html#method-i-register_observer","(&block)","<p>Register a block to be called when #run_match receives matched data. Method\ncallbacks can be registered …\n"],["run_match","Ionian::IO","Ionian/IO.html#method-i-run_match","(**kvargs)","<p>Start a thread that checks for data and notifies listeners. Passes kvargs\nto #read_match. This method …\n"],["unregister_observer","Ionian::IO","Ionian/IO.html#method-i-unregister_observer","(&block)","<p>Unregister a block from being called when matched data is received.\n"]]}}
1
+ var search_data = {"index":{"searchIndex":["ionian","io","expression()","expression=()","extended()","initialize_ionian()","on_match()","purge()","read_match()","register_observer()","run_match()","unregister_observer()"],"longSearchIndex":["ionian","ionian::io","ionian::io#expression()","ionian::io#expression=()","ionian::io::extended()","ionian::io#initialize_ionian()","ionian::io#on_match()","ionian::io#purge()","ionian::io#read_match()","ionian::io#register_observer()","ionian::io#run_match()","ionian::io#unregister_observer()"],"info":[["Ionian","","Ionian.html","","<p>A library to simplify interaction with IO streams. This includes network\nsockets, file sockets, and serial …\n"],["Ionian::IO","","Ionian/IO.html","","<p>A mixin for IO objects that allows regular expression matching and\nconvenient notification of received …\n"],["expression","Ionian::IO","Ionian/IO.html#method-i-expression","()","<p>Returns the regular expression used for #read_match.\n"],["expression=","Ionian::IO","Ionian/IO.html#method-i-expression-3D","(exp)","<p>Set the expression to match against the read buffer. Can be a regular\nexpression specifying capture groups, …\n"],["extended","Ionian::IO","Ionian/IO.html#method-c-extended","(obj)","<p>Called automaticallly when the object is extended with #extend.\n"],["initialize_ionian","Ionian::IO","Ionian/IO.html#method-i-initialize_ionian","()","<p>Initialize the Ionian instance variables. This is called automatically if\n#extend is called on an object. …\n"],["on_match","Ionian::IO","Ionian/IO.html#method-i-on_match","(&block)",""],["purge","Ionian::IO","Ionian/IO.html#method-i-purge","()","<p>Erase the data in the IO and Ionian buffers. This is typically handled\nautomatically.\n"],["read_match","Ionian::IO","Ionian/IO.html#method-i-read_match","(**kvargs, &block)","<p>Read matched data from the buffer. This method SHOULD NOT be used if\n#run_match is used.\n<p>Passes matches …\n"],["register_observer","Ionian::IO","Ionian/IO.html#method-i-register_observer","(&block)","<p>Register a block to be called when #run_match receives matched data. Method\ncallbacks can be registered …\n"],["run_match","Ionian::IO","Ionian/IO.html#method-i-run_match","(**kvargs)","<p>Start a thread that checks for data and notifies listeners (do |match,\nsocket|). Passes kvargs to #read_match …\n"],["unregister_observer","Ionian::IO","Ionian/IO.html#method-i-unregister_observer","(&block)","<p>Unregister a block from being called when matched data is received.\n"]]}}
@@ -44,13 +44,23 @@
44
44
  &mdash;
45
45
  <span class="container">Ionian::IO</span>
46
46
 
47
+ <li class="method">
48
+ <a href="Ionian/IO.html#method-i-expression">#expression</a>
49
+ &mdash;
50
+ <span class="container">Ionian::IO</span>
51
+
52
+ <li class="method">
53
+ <a href="Ionian/IO.html#method-i-expression-3D">#expression=</a>
54
+ &mdash;
55
+ <span class="container">Ionian::IO</span>
56
+
47
57
  <li class="method">
48
58
  <a href="Ionian/IO.html#method-i-initialize_ionian">#initialize_ionian</a>
49
59
  &mdash;
50
60
  <span class="container">Ionian::IO</span>
51
61
 
52
62
  <li class="method">
53
- <a href="Ionian/IO.html#method-i-match">#match</a>
63
+ <a href="Ionian/IO.html#method-i-on_match">#on_match</a>
54
64
  &mdash;
55
65
  <span class="container">Ionian::IO</span>
56
66
 
data/lib/ionian/io.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Ionian
2
2
  # A mixin for IO objects that allows regular expression matching
3
- # and convenient notification of data in the buffer.
3
+ # and convenient notification of received data.
4
4
  #
5
5
  # This module was designed to be EXTENDED by instantiated objects
6
6
  # that implement the standard library IO class.
@@ -9,32 +9,39 @@ module Ionian
9
9
  # Number of seconds to attempt an IO operation before timing out.
10
10
  # See standard library IO::select.
11
11
  attr_accessor :ionian_timeout
12
-
12
+
13
13
  # Called automaticallly when the object is extended with #extend.
14
14
  def self.extended(obj)
15
15
  obj.initialize_ionian
16
16
  end
17
-
17
+
18
18
  # Initialize the Ionian instance variables.
19
19
  # This is called automatically if #extend is called on an object.
20
20
  def initialize_ionian
21
- @ionian_listeners = []
22
- @ionian_buf = ''
23
- @ionian_expression = /(.*?)\n/
24
- @ionian_timeout = 1
21
+ @ionian_listeners = []
22
+ @ionian_buf = ''
23
+ @ionian_expression = /(.*?)\n/
24
+ @ionian_timeout = nil
25
+ @ionian_skip_select = false
26
+ @ionian_build_methods = true
25
27
  end
26
-
28
+
29
+ # Returns the regular expression used for #read_match.
30
+ def expression
31
+ @ionian_expression
32
+ end
33
+
27
34
  # Set the expression to match against the read buffer.
28
35
  # Can be a regular expression specifying capture groups,
29
36
  # or a string specifying the separator or line terminator
30
37
  # sequence. It is possible to use named captures in a
31
38
  # regex, which allows for convienient accessors like
32
39
  # match[:parameter].
33
- def match(expression)
34
- @ionian_expression = expression
35
- @ionian_expression = Regexp.new "(.*?)#{expression}" if expression.is_a? String
40
+ def expression=(exp)
41
+ @ionian_expression = exp
42
+ @ionian_expression = Regexp.new "(.*?)#{expression}" if exp.is_a? String
36
43
  end
37
-
44
+
38
45
  # Read matched data from the buffer.
39
46
  # This method SHOULD NOT be used if #run_match is used.
40
47
  #
@@ -49,47 +56,84 @@ module Ionian
49
56
  #
50
57
  # Data at the end of the buffer that is not matched can be accessed
51
58
  # in the last match with match.post_match. This data remains in the
52
- # buffer for the next read_match cycle. This is helpful for protocols
59
+ # buffer for the next #read_match cycle. This is helpful for protocols
53
60
  # like RS232 that do not have packet boundries.
54
61
  #
55
62
  # kvargs:
56
- # Timeout: Timeout in seconds IO::select will block.
63
+ # timeout: Timeout in seconds IO::select will block.
64
+ # skip_select: Skip over the IO::select statement. Use if you
65
+ # are calling IO::select ahead of this method.
66
+ # build_methods: Build method accessors from named captures.
67
+ # Enabled by default.
57
68
  def read_match(**kvargs, &block)
58
- timeout = kvargs.fetch :timeout, @ionian_timeout
69
+ timeout = kvargs.fetch :timeout, @ionian_timeout
70
+ skip_select = kvargs.fetch :skip_select, @ionian_skip_select
71
+ build_methods = kvargs.fetch :build_methods, @ionian_build_methods
59
72
 
60
- return nil unless IO.select [self], nil, nil, timeout
61
- @ionian_buf << read_partial 0xFFFF
73
+ unless skip_select
74
+ return nil unless ::IO.select [self], nil, nil, timeout
75
+ end
76
+
77
+ # Read data from the IO buffer until it's empty.
78
+ loop do
79
+ @ionian_buf << readpartial(0xFFFF)
80
+ break unless ::IO.select [self], nil, nil, 0
81
+ end
62
82
 
63
83
  @matches = []
64
84
 
65
85
  while @ionian_buf =~ @ionian_expression
66
86
  @matches << $~ # Match data.
67
- yield $~
87
+ yield $~ if block_given?
88
+ @ionian_buf = $' # Leave post match data in the buffer.
89
+ end
90
+
91
+ # Convert match parameters to methods.
92
+ if build_methods
93
+ @matches.each do |match|
94
+ match.names
95
+ .map {|name| name.to_sym}
96
+ .each {|symbol| match.singleton_class
97
+ .send(:define_method, symbol) { match[symbol] } \
98
+ unless match.respond_to? symbol
99
+ }
100
+ end
68
101
  end
69
102
 
70
- @ionian_buf = $' # Leave post match data in the buffer.
71
103
  @matches
72
- end
104
+ end
73
105
 
74
- # Start a thread that checks for data and notifies listeners.
106
+ # Start a thread that checks for data and notifies listeners (do |match, socket|).
75
107
  # Passes kvargs to #read_match.
76
108
  # This method SHOULD NOT be used if #read_match is used.
77
109
  def run_match(**kvargs)
78
110
  @match_listener ||= Thread.new do
79
- while not closed? do
80
- matches = read_match kvargs
81
- @ionian_listeners.each {|listener| yield matches} if matches
111
+ begin
112
+ while not closed? do
113
+ matches = read_match kvargs
114
+ matches.each {|match|
115
+ @ionian_listeners.each {|listener| listener.call match, self}
116
+ } if matches
117
+ end
118
+ rescue EOFError
119
+ rescue IOError
82
120
  end
83
121
 
84
122
  @match_listener = nil
85
123
  end
86
124
  end
87
-
88
- # Erase the data in Ionian's buffer.
125
+
126
+ # Erase the data in the IO and Ionian buffers.
127
+ # This is typically handled automatically.
89
128
  def purge
129
+ # Erase IO buffer.
130
+ while ::IO.select [self], nil, nil, 0
131
+ readpartial(0xFFFF)
132
+ end
133
+
90
134
  @ionian_buf = ''
91
135
  end
92
-
136
+
93
137
  # Register a block to be called when #run_match receives matched data.
94
138
  # Method callbacks can be registered with &object.method(:method).
95
139
  # Returns a reference to the given block.
@@ -98,13 +142,14 @@ module Ionian
98
142
  @ionian_listeners << block unless @ionian_listeners.include? block
99
143
  block
100
144
  end
101
-
145
+
146
+ alias_method :on_match, :register_observer
147
+
102
148
  # Unregister a block from being called when matched data is received.
103
149
  def unregister_observer(&block)
104
150
  @ionian_listeners.delete_if {|o| o == block}
105
151
  block
106
152
  end
107
-
153
+
108
154
  end
109
- end
110
-
155
+ end
data/lib/ionian.rb CHANGED
@@ -1 +1,8 @@
1
- require 'ionian/io'
1
+ require 'ionian/io'
2
+
3
+ # A library to simplify interaction with IO streams.
4
+ # This includes network sockets, file sockets, and
5
+ # serial streams like the console and RS232. Features
6
+ # regular expression matching and notification of
7
+ # received data.
8
+ module Ionian; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ionian
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex McLain
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-13 00:00:00.000000000 Z
11
+ date: 2013-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -66,60 +66,61 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description: A mixin for IO objects that allows regular expression matching and convenient
70
- notification of data in the buffer.
69
+ description: A library to simplify interaction with IO streams. This includes network
70
+ sockets, file sockets, and serial streams like the console and RS232. Features regular
71
+ expression matching and notification of received data.
71
72
  email: alex@alexmclain.com
72
73
  executables: []
73
74
  extensions: []
74
75
  extra_rdoc_files: []
75
76
  files:
76
- - doc/Ionian.html
77
- - doc/Ionian/IO.html
78
- - doc/created.rid
77
+ - license.txt
78
+ - lib/ionian.rb
79
+ - lib/ionian/io.rb
79
80
  - doc/fonts.css
80
- - doc/fonts/Lato-Light.ttf
81
- - doc/fonts/Lato-LightItalic.ttf
82
- - doc/fonts/Lato-Regular.ttf
83
- - doc/fonts/Lato-RegularItalic.ttf
84
- - doc/fonts/SourceCodePro-Bold.ttf
85
- - doc/fonts/SourceCodePro-Regular.ttf
86
- - doc/images/add.png
87
- - doc/images/arrow_up.png
81
+ - doc/images/page_green.png
88
82
  - doc/images/brick.png
89
- - doc/images/brick_link.png
83
+ - doc/images/wrench.png
84
+ - doc/images/find.png
85
+ - doc/images/bullet_toggle_plus.png
86
+ - doc/images/arrow_up.png
90
87
  - doc/images/bug.png
91
- - doc/images/bullet_black.png
92
88
  - doc/images/bullet_toggle_minus.png
93
- - doc/images/bullet_toggle_plus.png
94
- - doc/images/date.png
95
- - doc/images/delete.png
96
- - doc/images/find.png
97
- - doc/images/loadingAnimation.gif
98
- - doc/images/macFFBgHack.png
99
- - doc/images/package.png
100
- - doc/images/page_green.png
101
- - doc/images/page_white_text.png
89
+ - doc/images/wrench_orange.png
90
+ - doc/images/tag_blue.png
102
91
  - doc/images/page_white_width.png
92
+ - doc/images/page_white_text.png
93
+ - doc/images/package.png
94
+ - doc/images/bullet_black.png
103
95
  - doc/images/plugin.png
96
+ - doc/images/delete.png
97
+ - doc/images/brick_link.png
104
98
  - doc/images/ruby.png
105
- - doc/images/tag_blue.png
99
+ - doc/images/loadingAnimation.gif
100
+ - doc/images/date.png
101
+ - doc/images/add.png
102
+ - doc/images/zoom.png
106
103
  - doc/images/tag_green.png
104
+ - doc/images/macFFBgHack.png
107
105
  - doc/images/transparent.png
108
- - doc/images/wrench.png
109
- - doc/images/wrench_orange.png
110
- - doc/images/zoom.png
111
- - doc/index.html
112
- - doc/js/darkfish.js
106
+ - doc/js/searcher.js
113
107
  - doc/js/jquery.js
114
- - doc/js/navigation.js
115
108
  - doc/js/search.js
109
+ - doc/js/darkfish.js
116
110
  - doc/js/search_index.js
117
- - doc/js/searcher.js
118
- - doc/rdoc.css
111
+ - doc/js/navigation.js
112
+ - doc/Ionian.html
113
+ - doc/Ionian/IO.html
119
114
  - doc/table_of_contents.html
120
- - lib/ionian.rb
121
- - lib/ionian/io.rb
122
- - license.txt
115
+ - doc/created.rid
116
+ - doc/index.html
117
+ - doc/rdoc.css
118
+ - doc/fonts/Lato-RegularItalic.ttf
119
+ - doc/fonts/Lato-Light.ttf
120
+ - doc/fonts/Lato-LightItalic.ttf
121
+ - doc/fonts/SourceCodePro-Bold.ttf
122
+ - doc/fonts/Lato-Regular.ttf
123
+ - doc/fonts/SourceCodePro-Regular.ttf
123
124
  homepage: https://bitbucket.org/amclain/ionian
124
125
  licenses:
125
126
  - MIT
@@ -140,8 +141,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
141
  version: '0'
141
142
  requirements: []
142
143
  rubyforge_project:
143
- rubygems_version: 2.2.0.preview.1
144
+ rubygems_version: 2.1.11
144
145
  signing_key:
145
146
  specification_version: 4
146
- summary: Regular expression matching and notification for IO.
147
+ summary: Regular expression matching and notification for IO streams.
147
148
  test_files: []