rio 0.3.3 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. data/ChangeLog +225 -0
  2. data/README +12 -0
  3. data/Rakefile +1 -1
  4. data/VERSION +1 -1
  5. data/doc/ANNOUNCE +160 -71
  6. data/doc/RELEASE_NOTES +71 -2
  7. data/ex/colx.rb +1 -1
  8. data/ex/passwd_report.rb +4 -8
  9. data/ex/riocat +5 -5
  10. data/ex/riogunzip +1 -1
  11. data/ex/riogzip +6 -6
  12. data/ex/rioprompt.rb +6 -0
  13. data/lib/rio.rb +3 -13
  14. data/lib/rio/arycopy.rb +1 -1
  15. data/lib/rio/base.rb +1 -5
  16. data/lib/rio/construct.rb +75 -0
  17. data/lib/rio/constructor.rb +42 -11
  18. data/lib/rio/context.rb +1 -1
  19. data/lib/rio/context/dir.rb +50 -23
  20. data/lib/rio/context/methods.rb +5 -3
  21. data/lib/rio/{cxdir.rb → context/skip.rb} +24 -36
  22. data/lib/rio/context/stream.rb +38 -16
  23. data/lib/rio/cp.rb +24 -5
  24. data/lib/rio/dir.rb +8 -7
  25. data/lib/rio/doc/HOWTO.rb +33 -33
  26. data/lib/rio/doc/INTRO.rb +416 -256
  27. data/lib/rio/doc/MISC.rb +3 -1
  28. data/lib/rio/doc/SYNOPSIS.rb +28 -33
  29. data/lib/rio/entrysel.rb +76 -9
  30. data/lib/rio/file.rb +2 -1
  31. data/lib/rio/filter.rb +95 -0
  32. data/lib/rio/filter/closeoneof.rb +1 -1
  33. data/lib/rio/grande.rb +0 -74
  34. data/lib/rio/if.rb +2 -1
  35. data/lib/rio/if/basic.rb +1 -1
  36. data/lib/rio/if/csv.rb +1 -1
  37. data/lib/rio/if/dir.rb +1 -220
  38. data/lib/rio/if/fileordir.rb +26 -12
  39. data/lib/rio/if/grande.rb +55 -6
  40. data/lib/rio/if/grande_entry.rb +355 -0
  41. data/lib/rio/if/{methods.rb → grande_stream.rb} +69 -88
  42. data/lib/rio/if/path.rb +25 -3
  43. data/lib/rio/if/stream.rb +62 -37
  44. data/lib/rio/if/temp.rb +2 -2
  45. data/lib/rio/if/test.rb +23 -0
  46. data/lib/rio/impl/path.rb +5 -0
  47. data/lib/rio/match.rb +6 -3
  48. data/lib/rio/matchrecord.rb +50 -46
  49. data/lib/rio/{filter/chomp.rb → ops/construct.rb} +12 -20
  50. data/lib/rio/ops/create.rb +3 -0
  51. data/lib/rio/ops/dir.rb +12 -6
  52. data/lib/rio/ops/either.rb +17 -3
  53. data/lib/rio/ops/path.rb +4 -1
  54. data/lib/rio/ops/stream/input.rb +6 -1
  55. data/lib/rio/ops/stream/read.rb +1 -3
  56. data/lib/rio/{context/chomp.rb → prompt.rb} +17 -13
  57. data/lib/rio/rl/base.rb +1 -1
  58. data/lib/rio/rl/builder.rb +3 -1
  59. data/lib/rio/state.rb +7 -13
  60. data/lib/rio/stream.rb +8 -5
  61. data/lib/rio/stream/open.rb +1 -1
  62. data/lib/rio/version.rb +1 -1
  63. data/test/mswin32.rb +1 -1
  64. data/test/runtests_gem.rb +1 -1
  65. data/test/tc/all.rb +3 -0
  66. data/test/tc/copy-from.rb +13 -13
  67. data/test/tc/copy-to.rb +1 -1
  68. data/test/tc/copy.rb +1 -1
  69. data/test/tc/copydir.rb +0 -24
  70. data/test/tc/copysymlink.rb +39 -0
  71. data/test/tc/csv.rb +2 -2
  72. data/test/tc/csv2.rb +4 -4
  73. data/test/tc/misc.rb +16 -16
  74. data/test/tc/nolines.rb +26 -26
  75. data/test/tc/noqae.rb +74 -74
  76. data/test/tc/overload.rb +28 -28
  77. data/test/tc/riorl.rb +36 -0
  78. data/test/tc/selnosel.rb +36 -0
  79. data/test/tc/skip.rb +58 -0
  80. data/test/tc/skiplines.rb +42 -0
  81. data/test/tc/symlink.rb +1 -1
  82. data/test/tc/symlink0.rb +1 -1
  83. data/test/tc/temp.rb +1 -1
  84. data/test/tc/tempdir.rb +1 -1
  85. data/test/tc/testcase.rb +7 -1
  86. metadata +14 -8
  87. data/lib/rio/matchcolumns.rb +0 -266
  88. data/lib/rio/rangemath.rb +0 -44
@@ -41,28 +41,31 @@ module Doc
41
41
 
42
42
  = Rio - Ruby I/O Comfort Class
43
43
 
44
- Rio is a convenience class wrapping much of the functionality of
45
- IO, File, Dir, Pathname, FileUtils,
46
- Tempfile, StringIO, and OpenURI and uses Zlib, and CSV
47
- to extend that functionality using a simple consistent interface.
48
- Most of the instance methods of IO, File and Dir are simply forwarded to the appropriate handle
49
- to provide identical functionality. Rio also provides a "grande" interface that
50
- allows many application level IO tasks to be accomplished in line or two of code.
44
+ Rio is a convenience class wrapping much of the functionality of IO,
45
+ File, Dir, Pathname, FileUtils, Tempfile, StringIO, and OpenURI and
46
+ uses Zlib, and CSV to extend that functionality using a simple
47
+ consistent interface. Most of the instance methods of IO, File and
48
+ Dir are simply forwarded to the appropriate handle to provide
49
+ identical functionality. Rio also provides a "grande" interface that
50
+ allows many application level IO tasks to be accomplished in line or
51
+ two of code.
51
52
 
52
53
  Rio functionality can be broadly broken into three categories
53
54
  * path manipulation
54
55
  * file system access
55
56
  * stream manipulation
56
57
 
57
- Which methods are available to a given Rio, depends on the underlying object.
58
+ Which methods are available to a given Rio, depends on the underlying
59
+ object.
58
60
 
59
- A Rio generally does not need to be opened or have its mode specified.
60
- Most of Rio's methods simply configure it.
61
- When an actual IO operation is specified, Rio determines how to open it based
62
- on the object it is opening, the operation it is performing, and the options specified.
61
+ A Rio generally does not need to be opened or have its mode specified.
62
+ Most of Rio's methods simply configure it. When an actual IO
63
+ operation is specified, Rio determines how to open it based on the
64
+ object it is opening, the operation it is performing, and the options
65
+ specified.
63
66
 
64
- Rio configuration methods return the Rio for easy chaining and regard the presence of a block
65
- as an implied +each+.
67
+ Rio configuration methods return the Rio for easy chaining and regard
68
+ the presence of a block as an implied +each+.
66
69
 
67
70
  == Using a Rio
68
71
 
@@ -73,15 +76,18 @@ Using a Rio can be described as having 3 steps:
73
76
 
74
77
  === Creating a Rio
75
78
 
76
- Rio extends Kernel with one function +rio+, its constructor. This function is overloaded to
77
- create any type of Rio. +rio+ looks at the class and sometimes the value of its first argument
78
- to create an internal representation of the resource specified, additional arguments are used
79
- as needed by the resource type. The rio constructor does not initiate any io, it does not check
80
- for a resources existance or type. It neither knows nor cares what can be done with this Rio.
81
- Using methods like +respond_to?+ are meaningless at best and usually misleading.
79
+ Rio extends Kernel with one function +rio+, its constructor. This
80
+ function is overloaded to create any type of Rio. +rio+ looks at the
81
+ class and sometimes the value of its first argument to create an
82
+ internal representation of the resource specified, additional
83
+ arguments are used as needed by the resource type. The rio constructor
84
+ does not initiate any io, it does not check for a resources existance
85
+ or type. It neither knows nor cares what can be done with this Rio.
86
+ Using methods like <tt>respond_to?</tt> are meaningless at best and usually
87
+ misleading.
82
88
 
83
- For purposes of discussion, we divide Rios into two catagories, those that have a path
84
- and those that don't.
89
+ For purposes of discussion, we divide Rios into two catagories, those
90
+ that have a path and those that don't.
85
91
 
86
92
  ==== Creating a Rio that has a path
87
93
 
@@ -195,7 +201,8 @@ or
195
201
  or
196
202
  rio('tcp://hostname:port')
197
203
 
198
- ===== Creating a Rio that runs an external program and connects to its stdin and stdout
204
+ ===== Creating a Rio that runs an external program and connects to its
205
+ stdin and stdout
199
206
 
200
207
  <tt>rio(?-,cmd)</tt> (mnemonic: '-' is used by some Unix programs to specify stdin or stdout in place of a file)
201
208
 
@@ -207,21 +214,22 @@ This is Rio's interface to IO#popen
207
214
 
208
215
  === Path Manipulation
209
216
 
210
- Rio's path manipulation methods are for the most part simply forwarded to the File or URI classes with
211
- the return values converted to a Rio.
217
+ Rio's path manipulation methods are for the most part simply forwarded
218
+ to the File or URI classes with the return values converted to a Rio.
212
219
 
213
220
  ==== Creating a Rio from a Rio's component parts.
214
221
 
215
- The Rio methods for creating a Rio from a Rio's component parts are
216
- Rio#dirname, Rio#filename, Rio#basename, and Rio#extname.
217
- The behavior of Rio#basename depends on the setting of the +ext+
218
- configuration variable
219
- and is different from its counterpart in the File class. The default value of the +ext+ configuration variable
220
- is the string returned File#extname. The +ext+ configuration variable can be changed using Rio#ext and Rio#noext
221
- and can be queried using Rio#ext?. This value is used by calls to Rio#basename.
222
+ The Rio methods for creating a Rio from a Rio's component parts are
223
+ Rio#dirname, Rio#filename, Rio#basename, and Rio#extname. The
224
+ behavior of Rio#basename depends on the setting of the +ext+
225
+ configuration variable and is different from its counterpart in the
226
+ File class. The default value of the +ext+ configuration variable is
227
+ the string returned File#extname. The +ext+ configuration variable can
228
+ be changed using Rio#ext and Rio#noext and can be queried using
229
+ Rio#ext?. This value is used by calls to Rio#basename.
222
230
 
223
- Rio#filename returns the last component of a path, and is basically the same as +basename+ without consideration
224
- of an extension. So
231
+ Rio#filename returns the last component of a path, and is basically
232
+ the same as +basename+ without consideration of an extension.
225
233
 
226
234
  rio('afile.txt').basename #=> rio('afile')
227
235
  rio('afile.txt').filename #=> rio('afile.txt')
@@ -234,9 +242,10 @@ of an extension. So
234
242
 
235
243
  ==== Changing a path's component parts.
236
244
 
237
- Rio also provides methods for changing the component parts of its path.
238
- They are Rio#dirname=, Rio#filename=, Rio#basename=, and Rio#extname=. These
239
- methods replace the part extracted as described above with their argument.
245
+ Rio also provides methods for changing the component parts of its
246
+ path. They are Rio#dirname=, Rio#filename=, Rio#basename=, and
247
+ Rio#extname=. These methods replace the part extracted as described
248
+ above with their argument.
240
249
 
241
250
  ario = rio('dirA/dirB/afile.rb')
242
251
  ario.dirname = 'dirC' # rio('dirC/afile.rb')
@@ -244,31 +253,34 @@ methods replace the part extracted as described above with their argument.
244
253
  ario.extname = '.txt' # rio('dirC/bfile.txt')
245
254
  ario.filename = 'cfile.rb' # rio('dirC/cfile.rb')
246
255
 
247
- Rio also has a +rename+ mode which causes each of these to rename the actual file system
248
- object as well as changing the Rio. This is discussed in the section on
249
- Renaming and Moving.
250
-
256
+ Rio also has a +rename+ mode which causes each of these to rename the
257
+ actual file system object as well as changing the Rio. This is
258
+ discussed in the section on Renaming and Moving.
251
259
 
252
260
  ==== Splitting a Rio
253
261
 
254
- Rio#split returns an array of Rios, one for each path element. (Note that this behavior differs
255
- from File#split.)
262
+ Rio#split returns an array of Rios, one for each path element. (Note
263
+ that this behavior differs from File#split.)
256
264
 
257
265
  rio('a/b/c').split #=> [rio('a'),rio('b'),rio('c')]
258
266
 
259
- The array returned is extended with a +to_rio+ method, which will put the parts back together again.
267
+ The array returned is extended wwith a +to_rio+ method, which will put
268
+ the parts back together again.
260
269
 
261
270
  ary = rio('a/b/c').split #=> [rio('a'),rio('b'),rio('c')]
262
271
  ary.to_rio #=> rio('a/b/c')
263
272
 
264
273
  ==== Creating a Rio by specifying the individual parts of its path
265
274
 
266
- The first way to create a Rio by specifying its parts is to use the Rio constructor Rio#rio. Since
267
- a Rio is among the arguments the constructor will take, the constructor can be used.
275
+ The first way to create a Rio by specifying its parts is to use the
276
+ Rio constructor Rio#rio. Since a Rio is among the arguments the
277
+ constructor will take, the constructor can be used.
278
+
268
279
  ario = rio('adir')
269
280
  rio(ario,'b') #=> rio('adir/b')
270
281
 
271
- Rio#join and Rio#/ do the same thing, but the operator version <tt>/</tt> can take only one argument.
282
+ Rio#join and Rio#/ do the same thing, but the operator version
283
+ <tt>/</tt> can take only one argument.
272
284
 
273
285
  a = rio('a')
274
286
  b = rio('b')
@@ -284,9 +296,9 @@ The arguments to +join+ and <tt>/</tt> do not need to be Rios, of course
284
296
 
285
297
  ==== Manipulating a Rio path by treating it as a string.
286
298
 
287
- The Rio methods which treat a Rio as a string are Rio#sub, Rio#gsub and Rio#+.
288
- These methods create a new Rio using the string created by forwarding the method
289
- to the String returned by Rio#to_s.
299
+ The Rio methods which treat a Rio as a string are Rio#sub, Rio#gsub
300
+ and Rio#+. These methods create a new Rio using the string created by
301
+ forwarding the method to the String returned by Rio#to_s.
290
302
 
291
303
  ario = rio('dirA/dirB/afile') + '-1.1.1' # rio('dirA/dirB/afile-1.1.1')
292
304
  brio = ario.sub(/^dirA/, 'dirC') # rio('dirC/dirB/afile-1.1.1')
@@ -296,8 +308,8 @@ to the String returned by Rio#to_s.
296
308
 
297
309
  Rio#abs creates a new rio whose path is the absolute path of a Rio.
298
310
  If provided with an argument, it uses that as the base path, otherwise
299
- it uses an internal base path (usually the current working directory when
300
- it was created).
311
+ it uses an internal base path (usually the current working directory
312
+ when it was created).
301
313
 
302
314
  rio('/tmp').chdir do
303
315
  rio('a').abs #=> rio('/tmp/a')
@@ -311,60 +323,85 @@ Rio#rel creates a new rio with a path relative to a Rio.
311
323
  end
312
324
  rio('/tmp/b').rel('/tmp') #=> rio('b')
313
325
 
314
- Rio#route_to and Rio#route_from creates a new rio with a path representing
315
- the route to get to/from a Rio. They are based on the methods of the
316
- same names in the URI class
326
+ Rio#route_to and Rio#route_from creates a new rio with a path
327
+ representing the route to get to/from a Rio. They are based on the
328
+ methods of the same names in the URI class
317
329
 
318
330
  === Configuring a Rio
319
331
 
320
- The second step in using a rio is configuring it. Note that many times no configuration is necessary
321
- and that this is not a comprehensive list of all of Rio's configuration methods.
332
+ The second step in using a rio is configuring it. Note that many times
333
+ no configuration is necessary and that this is not a comprehensive
334
+ list of all of Rio's configuration methods.
322
335
 
323
336
  Rio's configuration mehods fall into three categories.
324
337
 
325
338
  [IO manipulators]
326
- An IO manipulator alters the behavior of a Rio's underlying IO object. These affect the behaviour
327
- of I/O methods which are forwarded directly to the underlying object as well as the grande I/O methods.
339
+
340
+ An IO manipulator alters the behavior of a Rio's underlying IO
341
+ object. These affect the behaviour of I/O methods which are
342
+ forwarded directly to the underlying object as well as the grande
343
+ I/O methods.
328
344
 
329
345
  [Grande configuration methods]
330
- The grande configuration methods affect the behaviour of Rio's grande I/O methods
346
+
347
+ The grande configuration methods affect the behaviour of Rio's
348
+ grande I/O methods
331
349
 
332
350
  [Grande selection methods]
333
- The grande selection methods select what data is returned by Rio's grande I/O methods
334
351
 
335
- All of Rio's configuration and selection methods can be passed a block, which will cause the Rio to behave as if
336
- +each+ had been called with the block after the method.
352
+ The grande selection methods select what data is returned by Rio's
353
+ grande I/O methods
354
+
355
+ All of Rio's configuration and selection methods can be passed a
356
+ block, which will cause the Rio to behave as if +each+ had been called
357
+ with the block after the method.
337
358
 
338
359
  ==== IO manipulators
339
360
 
340
361
  * +gzip+ a file on output, and ungzip it on input
362
+
341
363
  rio('afile.gz').gzip
342
- This causes the rio to read through a Zlib::GzipReader and to write Zlib::GzipWriter.
364
+
365
+ This causes the rio to read through a Zlib::GzipReader and to write
366
+ Zlib::GzipWriter.
343
367
 
344
368
  * +chomp+ lines as they are read
369
+
345
370
  rio('afile').chomp
346
- This causes a Rio to call String#chomp on the the String returned by all line oriented read operations.
371
+
372
+ This causes a Rio to call String#chomp on the the String returned by
373
+ all line oriented read operations.
347
374
 
348
375
  ==== Grande configuration methods
349
376
 
350
377
  * +all+, +recurse+, +norecurse+
378
+
351
379
  rio('adir').all
352
380
  rio('adir').norecurse('CVS')
353
- These methods instruct the Rio to also include entries in subdirectories when iterating through directories
354
- and control which subdirectories are included or excluded.
381
+
382
+ These methods instruct the Rio to also include entries in
383
+ subdirectories when iterating through directories and control which
384
+ subdirectories are included or excluded.
355
385
 
356
386
  * +bytes+
387
+
357
388
  rio('afile').bytes(1024)
358
- This causes a Rio to read the specified number of bytes at a time as a file is iterated through.
389
+
390
+ This causes a Rio to read the specified number of bytes at a time as
391
+ a file is iterated through.
359
392
 
360
393
  ==== Grande selection methods
361
394
 
362
- * +lines+, +nolines+
395
+ * +lines+, +skiplines+
396
+
363
397
  rio('afile').lines(0..9)
364
- rio('afile').nolines(/^\s*#/)
365
- Strictly speaking these are both configuration and selection methods. They configure the Rio to
366
- iterate through an input stream as lines. The arguments select which lines are actually returned.
367
- Lines are included (+lines+) or excluded (+nolines+) if they match *any* of the arguments as follows.
398
+ rio('afile').skiplines(/^\s*#/)
399
+
400
+ Strictly speaking these are both configuration and selection
401
+ methods. They configure the Rio to iterate through an input stream
402
+ as lines. The arguments select which lines are actually returned.
403
+ Lines are included (+lines+) or excluded (+skiplines+) if they match
404
+ *any* of the arguments as follows.
368
405
 
369
406
  If the argument is a:
370
407
  +RegExp+:: the line is matched against it
@@ -372,28 +409,35 @@ All of Rio's configuration and selection methods can be passed a block, which wi
372
409
  +Integer+:: the lineno is matched against it as if it were a one element range
373
410
  +Symbol+:: the symbol is +sent+ to the string; the line is included unless it returns false
374
411
  +Proc+:: the proc is called with the line as an argument; the line is included unless it returns false
412
+ +Array+:: an array containing any of the above, all of which must match for the line to be included
375
413
 
376
- * +entries+, +files+, +dirs+, +noentries+, +nofiles+, +nodirs+
414
+ * +entries+, +files+, +dirs+, +skipentries+, +skipfiles+, +skipdirs+
377
415
 
378
416
  rio('adir').files('*.txt')
379
- rio('adir').nofiles(/^\./)
417
+ rio('adir').skipfiles(/^\./)
380
418
 
381
- These methods select which entries will be returned when iterating throug directories.
382
- Entries are included (+entries+,+files+,+dirs+) or excluded(+noentries+,+nofiles+,+nodirs+) if they
383
- match *any* of the arguments as follows.
419
+ These methods select which entries will be returned when iterating
420
+ throug directories. Entries are included (+entries+,+files+,+dirs+)
421
+ or excluded(+skipentries+,+skipfiles+,+skipdirs+) if they match *any* of
422
+ the arguments as follows.
384
423
 
385
424
  If the argument is a:
386
425
  +String+:: the arg is treated as a glob; the filname is matched against it
387
426
  +RegExp+:: the filname is matched against it
388
427
  +Symbol+:: the symbol is +sent+ to the entry (a Rio); the entry is included unless it returns false
389
428
  +Proc+:: the proc is called with the entry (a Rio) as an argument; the entry is included unless it returns false
429
+ +Array+:: an array containing any of the above, all of which must match for the line to be included
430
+
431
+ * +records+, +rows+, +skiprecords+, +skiprows+
390
432
 
391
- * +records+, +rows+, +norecords+, +norows+
392
433
  rio('afile').bytes(1024).records(0...10)
393
- These select items from an input stream just as +lines+, but without specifying lines as the input
394
- record type. They can be used to select different record types in extension modules. The only
395
- such module at this writing is the CSV extension. In that case +records+ causes each line of
396
- a CSV file to be parsed into an array while +lines+ causes each line of the file to be returned normally.
434
+
435
+ These select items from an input stream just as +lines+, but without
436
+ specifying lines as the input record type. They can be used to
437
+ select different record types in extension modules. The only such
438
+ module at this writing is the CSV extension. In that case +records+
439
+ causes each line of a CSV file to be parsed into an array while
440
+ +lines+ causes each line of the file to be returned normally.
397
441
 
398
442
  === Rio I/O
399
443
 
@@ -404,11 +448,14 @@ As stated above the the three steps to using a Rio are:
404
448
 
405
449
  This section describes that final step.
406
450
 
407
- After creating and configuring a Rio, the file-system has not been accessed, no socket has been opened,
408
- not so much as a test for a files existance has been done. When an I/O method is called on a Rio, the
409
- sequence of events required to complete that operation on the underlying object takes place. Rio takes
410
- care of creating the apropriate object (eg IO,Dir), opening the object with the apropriate mode,
411
- performing the operation, closing the object if required, and returning the results of the operation.
451
+ After creating and configuring a Rio, the file-system has not been
452
+ accessed, no socket has been opened, not so much as a test for a files
453
+ existance has been done. When an I/O method is called on a Rio, the
454
+ sequence of events required to complete that operation on the
455
+ underlying object takes place. Rio takes care of creating the
456
+ apropriate object (eg IO,Dir), opening the object with the apropriate
457
+ mode, performing the operation, closing the object if required, and
458
+ returning the results of the operation.
412
459
 
413
460
  Rio's I/O operations can be divide into two catagories:
414
461
  * Proxy operations
@@ -416,107 +463,175 @@ Rio's I/O operations can be divide into two catagories:
416
463
 
417
464
  ==== Proxy operations
418
465
 
419
- These are calls which are forwarded to the underlying object (eg IO,Dir,Net::FTP), after apropriately
420
- creating and configuring that object. The result produced by the method is returned, and
421
- the object is closed.
466
+ These are calls which are forwarded to the underlying object (eg
467
+ IO,Dir,Net::FTP), after apropriately creating and configuring that
468
+ object. The result produced by the method is returned, and the object
469
+ is closed.
422
470
 
423
- In some cases the result is modified before being returned, as when a Rio is configured with +chomp+.
471
+ In some cases the result is modified before being returned, as when a
472
+ Rio is configured with +chomp+.
424
473
 
425
- In all cases, if the result returned by the underlying object, could itself be used for further I/O
426
- operations it is returned as a Rio. For example: where File#dirname returns a string, Rio#dirname
427
- returns a Rio; where Dir#read returns a string representing a directory entry, Rio#read
428
- returns a Rio.
474
+ In all cases, if the result returned by the underlying object, could
475
+ itself be used for further I/O operations it is returned as a Rio. For
476
+ example: where File#dirname returns a string, Rio#dirname returns a
477
+ Rio; where Dir#read returns a string representing a directory entry,
478
+ Rio#read returns a Rio.
429
479
 
430
- With some noteable exceptions, most of the operations available if one were using the underlying
431
- Ruby I/O class are available to the Rio and will behave identically.
480
+ With some noteable exceptions, most of the operations available if one
481
+ were using the underlying Ruby I/O class are available to the Rio and
482
+ will behave identically.
432
483
 
433
484
  For things that exist on a file system:
434
- * All the methods in FileTest are available as Rio instance methods. For example
485
+
486
+ * All the methods in FileTest are available as Rio instance
487
+ methods. For example
488
+
435
489
  FileTest.file?('afile')
490
+
436
491
  becomes
492
+
437
493
  rio('afile').file?
438
- * All the instance methods of +File+ except +path+ are available to a rio without change
494
+
495
+ * All the instance methods of +File+ except +path+ are available to a
496
+ rio without change
497
+
439
498
  * Most of the class methods of +File+ are available.
440
- * For those that take a filename as their only argument the calls are mapped to
441
- Rio instance methods as described above for FileTest.
499
+
500
+ * For those that take a filename as their only argument the calls
501
+ are mapped to Rio instance methods as described above for
502
+ FileTest.
503
+
442
504
  * +dirname+, and +readlink+ return Rios instead of strings
443
- * Rio has its own Rio#basename, Rio#join and Rio#symlink, which provide similar functionality.
444
- * The class methods which take multiple filenames (+chmod+,+chown+,+lchmod+,+lchown+) are available
445
- as Rio instance methods. For example
505
+
506
+ * Rio has its own Rio#basename, Rio#join and Rio#symlink, which
507
+ provide similar functionality.
508
+
509
+ * The class methods which take multiple filenames
510
+ (+chmod+,+chown+,+lchmod+,+lchown+) are available as Rio instance
511
+ methods. For example
512
+
446
513
  File.chmod(0666,'afile')
447
514
  becomes
448
515
  rio('afile').chmod(06660)
449
516
 
450
517
  For I/O Streams
451
518
 
452
- Most of the instance methods of IO are available, and most do the same thing, with some interface changes.
453
- <b>The big exception to this is the '<<' operator.</b> This is one of Rio's grande operators. While the symantics
454
- one would use to write to an IO object would actually accomplish the same thing with a Rio, It is a
455
- very different operator. Read the section on grande operators. The other differences between IO
456
- instance methods and the Rio equivelence can be summarized as follows.
457
- * The simple instance methods (eg +fcntl+, <tt>eof?</tt>, <tt>tty?</tt> etc.)
458
- are forwarded and the result returned as is
519
+ Most of the instance methods of IO are available, and most do the same
520
+ thing, with some interface changes. <b>The big exception to this is
521
+ the '<<' operator.</b> This is one of Rio's grande operators. While
522
+ the symantics one would use to write to an IO object would actually
523
+ accomplish the same thing with a Rio, It is a very different
524
+ operator. Read the section on grande operators. The other differences
525
+ between IO instance methods and the Rio equivelence can be summarized
526
+ as follows.
527
+
528
+ * The simple instance methods (eg +fcntl+, <tt>eof?</tt>,
529
+ <tt>tty?</tt> etc.) are forwarded and the result returned as is
530
+
459
531
  * Anywhere IO returns an IO, Rio returns a Rio
532
+
460
533
  * +close+ and its cousins return the Rio.
534
+
461
535
  * +each_byte+ and +each_line+ are forwarded as is.
462
- * All methods which read (read*,get*,each*) will cause the file to closed when the end of file is reached.
463
- This behavior is configurable, but the default is to close on eof
464
- * The methods which write (put*,print*) are forwarded as is; put* and print* return the Rio; write returns
465
- the value returned by IO#write; as mentioned above '<<' is a grande operator in Rio.
536
+
537
+ * All methods which read (read*,get*,each*) will cause the file to
538
+ closed when the end of file is reached. This behavior is
539
+ configurable, but the default is to close on eof
540
+
541
+ * The methods which write (put*,print*) are forwarded as is; put* and
542
+ print* return the Rio; write returns the value returned by IO#write;
543
+ as mentioned above '<<' is a grande operator in Rio.
466
544
 
467
545
  For directories:
468
546
 
469
- * all the instance methods of Dir are available except +each+ which is a grande method.
470
- * the class methods +mkdir+, +delete+, +rmdir+ are provided as instance methods.
471
- * +chdir+ is provided as an instance method. Rio#chdir returns a Rio and passes a Rio to a block if one is provided.
472
- * +glob+ is provided as an instance method, but returns an array of Rios
547
+ * all the instance methods of Dir are available except +each+ which is
548
+ a grande method.
549
+
550
+ * the class methods +mkdir+, +delete+, +rmdir+ are provided as
551
+ instance methods.
552
+
553
+ * +chdir+ is provided as an instance method. Rio#chdir returns a Rio
554
+ and passes a Rio to a block if one is provided.
555
+
556
+ * +glob+ is provided as an instance method, but returns an array of
557
+ Rios
558
+
473
559
  * +foreach+ is not supported
560
+
474
561
  * +each+ and <tt>[]</tt> have similar functionality provided by Rio
475
562
 
476
563
 
477
- For other Rios, instance methods are generally forwarded where appropriate. For example
564
+ For other Rios, instance methods are generally forwarded where
565
+ appropriate. For example
478
566
 
479
567
  * Rios that refer to StringIO objects forward 'string' and 'string='
480
- * Rios that refer to http URIs support all the Meta methods provided by open-uri
568
+
569
+ * Rios that refer to http URIs support all the Meta methods provided
570
+ by open-uri
481
571
 
482
572
 
483
573
  ==== Grande operators
484
574
 
485
- The primary grande operator is Rio#each. +each+ is used to iterate through Rios. When applied
486
- to a file it iterates through records in the file. When applied to a directory it iterates through
487
- the entries in the directory. Its behavior is modified by configuring the Rio prior to calling it using
488
- the configuration methods discussed above. Since iterating through things is ubiquitous in ruby, it is implied
489
- by the presence of a block after any of the grande configuration methods and many times does not need to be
490
- call explicitly. For example:
575
+ The primary grande operator is Rio#each. +each+ is used to iterate
576
+ through Rios. When applied to a file it iterates through records in
577
+ the file. When applied to a directory it iterates through the entries
578
+ in the directory. Its behavior is modified by configuring the Rio
579
+ prior to calling it using the configuration methods discussed
580
+ above. Since iterating through things is ubiquitous in ruby, it is
581
+ implied by the presence of a block after any of the grande
582
+ configuration methods and many times does not need to be call
583
+ explicitly. For example:
584
+
585
+ # iterate through chomped ruby comment lines
586
+ rio('afile.rb').chomp.lines(/^\s*#/) { |line| ... }
587
+
588
+ # iterate through all .rb files in 'adir' and its subdirectories
589
+ rio('adir').all.files('*.rb') { |f| ... }
491
590
 
492
- rio('afile.rb').chomp.lines(/^\s*#/) { |line| ... } # iterate through chomped ruby comment lines
493
- rio('adir').all.files('*.rb') { |f| ... } # iterate through all .rb files in 'adir' and its subdirectories
591
+ Because a Rio is an Enumerable, it supports +to_a+, which is the basis
592
+ for the grande subscript operator. Rio#[] with no arguments simply
593
+ calls to_a. With arguments it behaves as if those arguments had been
594
+ passed to the most recently called of the grande selection methods
595
+ listed above, and then calls to_a. For example to get the first ten
596
+ lines of a file into an array with lines chomped
494
597
 
495
- Because a Rio is an Enumerable, it supports +to_a+, which is the basis for the grande subscript operator.
496
- Rio#[] with no arguments simply calls to_a. With arguments it behaves as if those arguments had been
497
- passed to the most recently called of the grande selection methods listed above, and then calls to_a. For example
498
- to get the first ten lines of a file into an array with lines chomped
499
598
  rio('afile').chomp.lines(0...10).to_a
599
+
500
600
  can be written as
601
+
501
602
  rio('afile.gz').chomp.lines[0...10]
502
- or, to create an array of all the .c files in a directory, one could write
603
+
604
+ or, to create an array of all the .c files in a directory, one could
605
+ write
606
+
503
607
  rio('adir').files['*.c']
504
608
 
505
609
  The other grande operators are its copy operators. They are:
610
+
506
611
  * <tt><</tt> (copy-from)
612
+
507
613
  * <tt><<</tt> (append-from)
614
+
508
615
  * <tt>></tt> (copy-to)
616
+
509
617
  * <tt>>></tt> (append-to)
510
- The only difference between the 'copy' and 'append' versions is how they deal with an unopened resource.
511
- In the former the open it with mode 'w' and in the latter, mode 'a'.
512
- Beyond that, their behavior can be summarized as:
618
+
619
+ The only difference between the 'copy' and 'append' versions is how
620
+ they deal with an unopened resource. In the former the open it with
621
+ mode 'w' and in the latter, mode 'a'. Beyond that, their behavior can
622
+ be summarized as:
623
+
513
624
  source.each do |entry|
514
625
  destination << entry
515
626
  end
516
- Since they are based on the +each+ operator, all of the selection and configuration options are available.
517
- And the right-hand-side argument of the operators are not restricted to Rios -- Strings and Arrays are also supported.
627
+
628
+ Since they are based on the +each+ operator, all of the selection and
629
+ configuration options are available. And the right-hand-side argument
630
+ of the operators are not restricted to Rios -- Strings and Arrays are
631
+ also supported.
518
632
 
519
633
  For example:
634
+
520
635
  rio('afile') > astring # copy a file into a string
521
636
 
522
637
  rio('afile').chomp > anarray # copy the chomped lines of afile into an array
@@ -529,31 +644,34 @@ For example:
529
644
 
530
645
  rio('adir').dirs.files('README') > rio('bdir') # same thing, but only README files
531
646
 
532
- rio(?-,'ps -a').nolines(0,/ps$/) > anarray # copy the output of th ps command into an array, skippying
647
+ rio(?-,'ps -a').skiplines(0,/ps$/) > anarray # copy the output of th ps command into an array, skippying
533
648
  # the header line and the ps command entry
534
649
 
535
650
  === Renaming and Moving
536
651
 
537
- Rio provides two methods for directly renaming objects on the filesystem:
538
- Rio#rename and Rio#rename!. Both of these use File#rename. The difference
539
- between them is the returned Rio. Rio#rename leaves the path of the Rio unchanged,
540
- while Rio#rename! changes the path of the Rio to refer to the renamed path.
652
+ Rio provides two methods for directly renaming objects on the
653
+ filesystem: Rio#rename and Rio#rename!. Both of these use
654
+ File#rename. The difference between them is the returned
655
+ Rio. Rio#rename leaves the path of the Rio unchanged, while
656
+ Rio#rename! changes the path of the Rio to refer to the renamed path.
657
+
541
658
  ario = rio('a')
542
659
  ario.rename('b') # file 'a' has been renamed to 'b' but 'ario' => rio('a')
543
660
  ario.rename!('b') # file 'a' has been renamed to 'b' and 'ario' => rio('b')
544
661
 
545
- Rio also has a +rename+ mode, which causes the path manipulation methods Rio#dirname=,
546
- Rio#filename=, Rio#basename= and Rio#extname= to rename an object on the filesystem
547
- when they are used to change a Rio's path. A Rio is put in +rename+ mode by
548
- calling Rio#rename with no arguments.
662
+ Rio also has a +rename+ mode, which causes the path manipulation
663
+ methods Rio#dirname=, Rio#filename=, Rio#basename= and Rio#extname= to
664
+ rename an object on the filesystem when they are used to change a
665
+ Rio's path. A Rio is put in +rename+ mode by calling Rio#rename with
666
+ no arguments.
549
667
 
550
668
  rio('adir/afile.txt').rename.filename = 'bfile.rb' # adir/afile.txt => adir/bfile.rb
551
669
  rio('adir/afile.txt').rename.basename = 'bfile' # adir/afile.txt => adir/bfile.txt
552
670
  rio('adir/afile.txt').rename.extname = '.rb' # adir/afile.txt => adir/afile.rb
553
671
  rio('adir/afile.txt').rename.dirname = 'b/c' # adir/afile.txt => b/c/afile.txt
554
672
 
555
- When +rename+ mode is set for a directory Rio, it is automatically set in the Rios created
556
- when iterating through that directory.
673
+ When +rename+ mode is set for a directory Rio, it is automatically set
674
+ in the Rios created when iterating through that directory.
557
675
 
558
676
  rio('adir').rename.files('*.htm') do |frio|
559
677
  frio.extname = '.html' #=> changes the rio and renames the file
@@ -561,10 +679,11 @@ when iterating through that directory.
561
679
 
562
680
  === Deleting
563
681
 
564
- The Rio methods for deleting filesystem objects are Rio#rm, Rio#rmdir, Rio#rmtree, Rio#delete,
565
- and Rio#delete!. +rm+, +rmdir+ and +rmtree+ are passed the like named methods in the FileUtils
566
- module. Rio#delete calls +rmdir+ for directories and +rm+ for anything else, while Rio#delete!
567
- calls Rio#rmtree for directories.
682
+ The Rio methods for deleting filesystem objects are Rio#rm, Rio#rmdir,
683
+ Rio#rmtree, Rio#delete, and Rio#delete!. +rm+, +rmdir+ and +rmtree+
684
+ are passed the like named methods in the FileUtils module. Rio#delete
685
+ calls +rmdir+ for directories and +rm+ for anything else, while
686
+ Rio#delete! calls Rio#rmtree for directories.
568
687
 
569
688
  * To delete something only if it is not a directory use Rio#rm
570
689
  * To delete an empty directory use Rio#rmdir
@@ -572,13 +691,17 @@ calls Rio#rmtree for directories.
572
691
  * To delete anything except a populated directory use Rio#delete
573
692
  * To delete anything use Rio#delete!
574
693
 
575
- It is not an error to call any of the deleting methods on something that does not exist. Rio provides
576
- Rio#exist? and Rio#symlink? to check if something exists (<tt>exist?</tt> returns false for
577
- symlinks to non-existant object even though the symlink itself exists).
578
- The deleting methods' purpose is to make things not exist, so
579
- calling one of them on something that already does not exist is considered a success.
694
+ It is not an error to call any of the deleting methods on something
695
+ that does not exist. Rio provides Rio#exist? and Rio#symlink? to check
696
+ if something exists (<tt>exist?</tt> returns false for symlinks to
697
+ non-existant object even though the symlink itself exists). The
698
+ deleting methods' purpose is to make things not exist, so calling one
699
+ of them on something that already does not exist is considered a
700
+ success.
701
+
702
+ To create a clean copy of a directory whether or not anything with
703
+ that name exists one might do this
580
704
 
581
- To create a clean copy of a directory whether or not anything with that name exists one might do this
582
705
  rio('adir').delete!.mkpath.chdir do
583
706
  # do something in adir
584
707
  end
@@ -590,37 +713,47 @@ To create a clean copy of a directory whether or not anything with that name exi
590
713
 
591
714
  ==== Using Symbolic Links
592
715
 
593
- To create a symbolic link (symlink) to the file-system entry refered to by a Rio, use Rio#symlink.
594
- Rio#symlink differs from File#symlink in that it calculates the path from the symlink location to
595
- the Rio's position. So:
716
+ To create a symbolic link (symlink) to the file-system entry refered
717
+ to by a Rio, use Rio#symlink. Rio#symlink differs from File#symlink
718
+ in that it calculates the path from the symlink location to the Rio's
719
+ position.
596
720
 
597
721
  File#symlink('adir/afile','adir/alink')
598
722
 
599
- creates a symlink in the directory 'adir' named 'alink' which references 'adir/afile'. From the
600
- perspective of 'alink', 'adir/afile' does not exist. While:
723
+ creates a symlink in the directory 'adir' named 'alink' which
724
+ references 'adir/afile'. From the perspective of 'alink', 'adir/afile'
725
+ does not exist. While:
601
726
 
602
727
  rio('adir/afile').symlink('adir/alink')
603
728
 
604
- creates a symlink in the directory 'adir' named 'alink' which references 'afile'. This is the route
605
- to 'adir/afile' from the perspective of 'adir/alink'.
729
+ creates a symlink in the directory 'adir' named 'alink' which
730
+ references 'afile'. This is the route to 'adir/afile' from the
731
+ perspective of 'adir/alink'.
606
732
 
607
- Note that the return value from +symlink+ is the calling Rio and not a Rio refering to the symlink.
608
- This is done for consistency with the rest of Rio.
733
+ Note that the return value from +symlink+ is the calling Rio and not a
734
+ Rio refering to the symlink. This is done for consistency with the
735
+ rest of Rio.
736
+
737
+ Rio#symlink? can be used to test if a file-system object is a
738
+ symlink. A Rio is extended with Rio#readlink, and Rio#lstat only if
739
+ Rio#symlink? returns true. So for non-symlinks, these will raise a
740
+ NoMethodError. These are both passed to their counterparts in
741
+ File. Rio#readlink returns a Rio refering to the result of
742
+ File#readlink.
609
743
 
610
- Rio#symlink? can be used to test if a file-system object is a symlink. A Rio is extended with
611
- Rio#readlink, and Rio#lstat only if Rio#symlink? returns true. So for non-symlinks, these
612
- will raise a NoMethodError. These are both passed to their counterparts in File. Rio#readlink
613
- returns a Rio refering to the result of File#readlink.
614
744
 
615
745
  ==== Using A Rio as an IO (or File or Dir)
616
746
 
617
- Rio supports so much of IO's interface that one might be tempted to pass it to a method that
618
- expects an IO. While Rio is not and is not intended to be a stand in for IO, this can work.
619
- It requires knowledge of every IO method that will be called, under any circumstances.
747
+ Rio supports so much of IO's interface that one might be tempted to
748
+ pass it to a method that expects an IO. While Rio is not and is not
749
+ intended to be a stand in for IO, this can work. It requires
750
+ knowledge of every IO method that will be called, under any
751
+ circumstances.
620
752
 
621
- Even in cases where Rio supports the required IO interface, A Rio feature that seems to
622
- cause the most incompatibility, is its automatic closing of files. To turn off all of Rio's
623
- automatic closing use Rio#noautoclose.
753
+ Even in cases where Rio supports the required IO interface, A Rio
754
+ feature that seems to cause the most incompatibility, is its automatic
755
+ closing of files. To turn off all of Rio's automatic closing use
756
+ Rio#noautoclose.
624
757
 
625
758
  For example:
626
759
  require 'yaml'
@@ -628,92 +761,110 @@ For example:
628
761
  YAML.dump( ['badger', 'elephant', 'tiger'], yrio )
629
762
  obj = YAML::load( yrio ) #=> ["badger", "tiger", "elephant"]
630
763
 
631
- ==== Automatic Closing of Files
764
+
765
+ ==== Automatically Closing Files
632
766
 
633
767
  Rio closes files automatically in three instances.
634
768
 
635
- When reading from an IO it is closed when the end of file is reached. While
636
- this is a reasonable thing to do in many cases, sometimes this is not desired.
637
- To turn Rio's automatic closing on end of file use Rio#nocloseoneof (it can
638
- be turned back on via Rio#closeoneof)
769
+ When reading from an IO it is closed when the end of file is
770
+ reached. While this is a reasonable thing to do in many cases,
771
+ sometimes this is not desired. To turn Rio's automatic closing on end
772
+ of file use Rio#nocloseoneof (it can be turned back on via
773
+ Rio#closeoneof)
639
774
 
640
775
  ario = rio('afile').nocloseoneof
641
776
  lines = ario[]
642
777
  ario.closed? #=> false
643
778
 
644
- Closing on end-of-file is necessary for many of Rio's "one-liners", but has an
645
- implication that may be surprising at first. A Rio starts life as a path, not
646
- much more than a string. When one of its read methods is called it becomes an
647
- input stream. When the stream is closed, it becomes a path again. This means
648
- that when reading from a Rio, the end-of-file condition is seen only once before it
649
- becomes a path again, and will be reopened if another read operation is attempted.
650
-
651
- Another time a Rio will be closed atomatically is when writing to it with one
652
- of the copy operators (<tt><, <<, >, >></tt>).
653
- This behavior can be turned off with Rio#nocloseoncopy.
654
-
655
- To turn off both of thes types of automatic closing use Rio#noautoclose.
656
-
657
- The third instance when Rio will close a file automatically is when a file opened
658
- for one type of access receives a method which that access mode does not support.
659
- So, the code
660
- rio('afile').puts("Hello World").gets
661
- will open the file for write access when the +puts+ method is received. When +gets+ is
662
- called the file is closed and reopened with read access.
663
-
664
- ==== Explicit Closing of Files
665
-
666
- Rio can not determine when the client is finished writing to it, as it does
667
- using +eof+ on read. It is the author's understanding that Ruby does not support
668
- a mechanism to have code run when there are no more references to it -- that finalizers
669
- are not necessarily run immediatly upon an object's reference count reaching 0.
670
- If this understanding is incorrect, some of Rio's extranious ways of closing a file
671
- may be rethought.
672
-
673
- That being said, Rio support several ways to explicitly close a file. Rio#close will close
674
- any open Rio. The output methods Rio#puts!, Rio#putc!, Rio#printf!, Rio#print!, and Rio#write!
675
- behave as if their counterparts without the exclamation point had been called and
676
- then call Rio#close or Rio#close_write if the underlying IO object is opened for duplex access.
779
+ Closing on end-of-file is necessary for many of Rio's one-liners, but
780
+ has an implication that may be surprising at first. A Rio starts life
781
+ as a path, not much more than a string. When one of its read methods
782
+ is called it becomes an input stream. When the stream is closed, it
783
+ becomes a path again. This means that when reading from a Rio, the
784
+ end-of-file condition is seen only once before it becomes a path
785
+ again, and will be reopened if another read operation is attempted.
786
+
787
+ Another time a Rio will be closed atomatically is when writing to it
788
+ with one of the copy operators (<tt><, <<, >, >></tt>). This behavior
789
+ can be turned off with Rio#nocloseoncopy.
790
+
791
+ To turn off both of thes types of automatic closing use
792
+ Rio#noautoclose.
793
+
794
+ The third instance when Rio will close a file automatically is when a
795
+ file opened for one type of access receives a method which that access
796
+ mode does not support. So, the code rio('afile').puts("Hello
797
+ World").gets will open the file for write access when the +puts+
798
+ method is received. When +gets+ is called the file is closed and
799
+ reopened with read access.
800
+
801
+ ==== Explicitly Closing Files
802
+
803
+ Rio can not determine when the client is finished writing to it, as it
804
+ does using +eof+ on read. It is the author's understanding that Ruby
805
+ does not support a mechanism to have code run when there are no more
806
+ references to it -- that finalizers are not necessarily run immediatly
807
+ upon an object's reference count reaching 0. If this understanding is
808
+ incorrect, some of Rio's extranious ways of closing a file may be
809
+ rethought.
810
+
811
+ That being said, Rio support several ways to explicitly close a
812
+ file. Rio#close will close any open Rio. The output methods Rio#puts!,
813
+ Rio#putc!, Rio#printf!, Rio#print!, and Rio#write! behave as if their
814
+ counterparts without the exclamation point had been called and then
815
+ call Rio#close or Rio#close_write if the underlying IO object is
816
+ opened for duplex access.
677
817
 
678
818
 
679
819
  ==== Open mode selection
680
820
 
681
- A Rio is typically not explicitly opened. It opens a file automatically when an
682
- input or output methed is called. For output methods Rio opens a file with mode 'w',
683
- and otherwise opens a file with mode 'r'. This behavior can be modified using the
684
- tersely named methods Rio#a, Rio#a!, Rio#r, Rio#r!, Rio#w, and Rio#w!, which cause
821
+ A Rio is typically not explicitly opened. It opens a file
822
+ automatically when an input or output methed is called. For output
823
+ methods Rio opens a file with mode 'w', and otherwise opens a file
824
+ with mode 'r'. This behavior can be modified using the tersely named
825
+ methods Rio#a, Rio#a!, Rio#r, Rio#r!, Rio#w, and Rio#w!, which cause
685
826
  the Rio to use modes 'a','a+','r','r+','w',and 'w+' respectively.
686
827
 
687
828
  One way to append a string to a file and close it in one line is
829
+
688
830
  rio('afile').a.puts!("Hello World")
689
831
 
690
832
  Run a cmd that must be opened for read and write
833
+
691
834
  ans = rio(?-,'cat').w!.puts!("Hello Kitty").readlines
692
835
 
693
- The automatic selection of mode can be bypassed entirely using Rio#mode and Rio#open.
836
+ The automatic selection of mode can be bypassed entirely using
837
+ Rio#mode and Rio#open.
694
838
 
695
- If a mode is specified using +mode+, the file will still be opened automatically, but
696
- the mode specified in the +mode+ method will be used regardless of whether it makes sense.
839
+ If a mode is specified using +mode+, the file will still be opened
840
+ automatically, but the mode specified in the +mode+ method will be
841
+ used regardless of whether it makes sense.
697
842
 
698
- A Rio can also be opened explicitly using Rio#open. +open+ takes one parameter, a mode.
699
- This also will override all of Rio's automatic mode selection.
843
+ A Rio can also be opened explicitly using Rio#open. +open+ takes one
844
+ parameter, a mode. This also will override all of Rio's automatic
845
+ mode selection.
700
846
 
701
847
 
702
848
  ==== CSV mode
703
849
 
704
- Rio uses the CSV class from the Ruby standard library to provide support for reading
705
- and writing comma-separated-value files. Normally using <tt>(no)records</tt> is
706
- identical to <tt>(no)lines</tt> because while +records+ only selects and does not
707
- specify the record-type, lines is the default, and so
850
+ Rio uses the CSV class from the Ruby standard library to provide
851
+ support for reading and writing comma-separated-value files. Normally
852
+ using <tt>(no)records</tt> is identical to <tt>(no)lines</tt> because
853
+ while +records+ only selects and does not specify the record-type,
854
+ +lines+ is the default.
855
+
708
856
  rio('afile').records(1..2)
857
+
709
858
  effectively means
859
+
710
860
  rio('afile').lines.records(1..2)
711
861
 
712
- The CSV extension distingishes between items selected using Rio#records and those
713
- selected using Rio#lines. Rio returns records parsed into Arrays by the CSV
714
- library when +records+ is used, and returns Strings as normal when +lines+ is used.
715
- +records+ is the default
716
- So:
862
+ The CSV extension distingishes between items selected using
863
+ Rio#records and those selected using Rio#lines. Rio returns records
864
+ parsed into Arrays by the CSV library when +records+ is used, and
865
+ returns Strings as normal when +lines+ is used. +records+ is the
866
+ default.
867
+
717
868
  rio('f.csv').puts!(["h0,h1","f0,f1"])
718
869
 
719
870
  rio('f.csv').csv.records[] #==>[["h0", "h1"], ["f0", "f1"]]
@@ -722,23 +873,29 @@ So:
722
873
  rio('f.csv').csv.records[0] #==>[["h0", "h1"]]
723
874
  rio('f.csv').csv[0] #==> same thing
724
875
  rio('f.csv').csv.lines[0] #==>["h0,h1\n"]
725
- rio('f.csv').csv.norecords[0] #==>[["f0", "f1"]]
726
- rio('f.csv').csv.nolines[0] #==>["f0,f1\n"]
876
+ rio('f.csv').csv.skiprecords[0] #==>[["f0", "f1"]]
877
+ rio('f.csv').csv.skiplines[0] #==>["f0,f1\n"]
878
+
879
+ This distinction, of course, applies equally when using the copy
880
+ operators and +each+
727
881
 
728
- This distinction, of course, applies equally when using the copy operators and +each+
729
882
  rio('f.csv').csv[0] > rio('out').csv # out contains "f0,f1\n"
883
+
730
884
  rio('f.csv').csv { |array_of_fields| ... }
731
885
 
732
- Notice that +csv+ mode is called on both the input and output Rios. The +csv+ on the
733
- 'out' Rio causes it to treat an array written to it as an array of records which is
734
- converted into CSV format before writing. Without the +csv+, the output would be
735
- written as if Array#to_s on [["f0","f1"]] had been called
886
+ Notice that +csv+ mode is called on both the input and output
887
+ Rios. The +csv+ on the 'out' Rio causes it to treat an array written
888
+ to it as an array of records which is converted into CSV format before
889
+ writing. Without the +csv+, the output would be written as if
890
+ Array#to_s on [["f0","f1"]] had been called
891
+
736
892
  rio('f.csv').csv[0] > rio('out') # out contains "f0f1"
737
893
 
738
- The String representing a record that is returned when using +lines+ is extended with a
739
- +to_a+ method which will parse it into an array of fields. Likewise the Array returned
740
- when a record is returned using +records+ is extended with a modified +to_s+ which
741
- treats it as an array CSV fields, rather than just an array of strings.
894
+ The String representing a record that is returned when using +lines+
895
+ is extended with a +to_a+ method which will parse it into an array of
896
+ fields. Likewise the Array returned when a record is returned using
897
+ +records+ is extended with a modified +to_s+ which treats it as an
898
+ array CSV fields, rather than just an array of strings.
742
899
 
743
900
  array_of_lines = rio('f.csv').csv.lines[1] #==>["f0,f1\n"]
744
901
  array_of_records = rio('f.csv').csv.records[1] #==>[["f0", "f1"]]
@@ -746,20 +903,22 @@ treats it as an array CSV fields, rather than just an array of strings.
746
903
  array_of_lines[0].to_a #==>["f0", "f1"]
747
904
  array_of_records[0].to_s #==>"f0,f1"
748
905
 
749
- Rio#csv takes two optional parameters, which are passed on to the CSV library. They are
750
- the +field_separator+ and the +record_separator+.
906
+ Rio#csv takes two optional parameters, which are passed on to the CSV
907
+ library. They are the +field_separator+ and the +record_separator+.
908
+
751
909
  rio('semisep').puts!(["h0;h1","f0;f1"])
752
910
 
753
911
  rio('semisep').csv(';').to_a #==>[["h0", "h1"], ["f0", "f1"]]
754
912
 
755
- These are specified independently on the source and destination when using the
756
- copy operators, So:
913
+ These are specified independently on the source and destination when
914
+ using the copy operators.
757
915
 
758
916
  rio('semisep').csv(';') > rio('colonsep').csv(':')
759
- rio('colonsep').slurp #==>"h0:h1\nf0:f1\n"
917
+ rio('colonsep').contents #==>"h0:h1\nf0:f1\n"
760
918
 
761
- Rio provides two methods for selecting fields from CSV records in a manner similar
762
- to that provided for selecting lines -- Rio#columns and Rio#nocolumns.
919
+ Rio provides two methods for selecting fields from CSV records in a
920
+ manner similar to that provided for selecting lines -- Rio#columns and
921
+ Rio#nocolumns.
763
922
 
764
923
  rio('f.csv').puts!(["h0,h1,h2,h3","f0,f1,f2,f3"])
765
924
 
@@ -768,10 +927,11 @@ to that provided for selecting lines -- Rio#columns and Rio#nocolumns.
768
927
  rio('f.csv').csv.columns(1..2).to_a #==>[["h1", "h2"], ["f1", "f2"]]
769
928
  rio('f.csv').csv.nocolumns(1..2).to_a #==>[["h0", "h3"], ["f0", "f3"]]
770
929
 
771
- Rio#columns can, of course be used with the +each+ and the copy operators:
930
+ Rio#columns can, of course be used with the +each+ and the copy
931
+ operators:
772
932
 
773
933
  rio('f.csv').csv.columns(0..1) > rio('out').csv
774
- rio('out').slurp #==>"h0,h1\nf0,f1\n"
934
+ rio('out').contents #==>"h0,h1\nf0,f1\n"
775
935
 
776
936
 
777
937
  ---