rio 0.3.3 → 0.3.4

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