rio 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +225 -0
- data/README +12 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/doc/ANNOUNCE +160 -71
- data/doc/RELEASE_NOTES +71 -2
- data/ex/colx.rb +1 -1
- data/ex/passwd_report.rb +4 -8
- data/ex/riocat +5 -5
- data/ex/riogunzip +1 -1
- data/ex/riogzip +6 -6
- data/ex/rioprompt.rb +6 -0
- data/lib/rio.rb +3 -13
- data/lib/rio/arycopy.rb +1 -1
- data/lib/rio/base.rb +1 -5
- data/lib/rio/construct.rb +75 -0
- data/lib/rio/constructor.rb +42 -11
- data/lib/rio/context.rb +1 -1
- data/lib/rio/context/dir.rb +50 -23
- data/lib/rio/context/methods.rb +5 -3
- data/lib/rio/{cxdir.rb → context/skip.rb} +24 -36
- data/lib/rio/context/stream.rb +38 -16
- data/lib/rio/cp.rb +24 -5
- data/lib/rio/dir.rb +8 -7
- data/lib/rio/doc/HOWTO.rb +33 -33
- data/lib/rio/doc/INTRO.rb +416 -256
- data/lib/rio/doc/MISC.rb +3 -1
- data/lib/rio/doc/SYNOPSIS.rb +28 -33
- data/lib/rio/entrysel.rb +76 -9
- data/lib/rio/file.rb +2 -1
- data/lib/rio/filter.rb +95 -0
- data/lib/rio/filter/closeoneof.rb +1 -1
- data/lib/rio/grande.rb +0 -74
- data/lib/rio/if.rb +2 -1
- data/lib/rio/if/basic.rb +1 -1
- data/lib/rio/if/csv.rb +1 -1
- data/lib/rio/if/dir.rb +1 -220
- data/lib/rio/if/fileordir.rb +26 -12
- data/lib/rio/if/grande.rb +55 -6
- data/lib/rio/if/grande_entry.rb +355 -0
- data/lib/rio/if/{methods.rb → grande_stream.rb} +69 -88
- data/lib/rio/if/path.rb +25 -3
- data/lib/rio/if/stream.rb +62 -37
- data/lib/rio/if/temp.rb +2 -2
- data/lib/rio/if/test.rb +23 -0
- data/lib/rio/impl/path.rb +5 -0
- data/lib/rio/match.rb +6 -3
- data/lib/rio/matchrecord.rb +50 -46
- data/lib/rio/{filter/chomp.rb → ops/construct.rb} +12 -20
- data/lib/rio/ops/create.rb +3 -0
- data/lib/rio/ops/dir.rb +12 -6
- data/lib/rio/ops/either.rb +17 -3
- data/lib/rio/ops/path.rb +4 -1
- data/lib/rio/ops/stream/input.rb +6 -1
- data/lib/rio/ops/stream/read.rb +1 -3
- data/lib/rio/{context/chomp.rb → prompt.rb} +17 -13
- data/lib/rio/rl/base.rb +1 -1
- data/lib/rio/rl/builder.rb +3 -1
- data/lib/rio/state.rb +7 -13
- data/lib/rio/stream.rb +8 -5
- data/lib/rio/stream/open.rb +1 -1
- data/lib/rio/version.rb +1 -1
- data/test/mswin32.rb +1 -1
- data/test/runtests_gem.rb +1 -1
- data/test/tc/all.rb +3 -0
- data/test/tc/copy-from.rb +13 -13
- data/test/tc/copy-to.rb +1 -1
- data/test/tc/copy.rb +1 -1
- data/test/tc/copydir.rb +0 -24
- data/test/tc/copysymlink.rb +39 -0
- data/test/tc/csv.rb +2 -2
- data/test/tc/csv2.rb +4 -4
- data/test/tc/misc.rb +16 -16
- data/test/tc/nolines.rb +26 -26
- data/test/tc/noqae.rb +74 -74
- data/test/tc/overload.rb +28 -28
- data/test/tc/riorl.rb +36 -0
- data/test/tc/selnosel.rb +36 -0
- data/test/tc/skip.rb +58 -0
- data/test/tc/skiplines.rb +42 -0
- data/test/tc/symlink.rb +1 -1
- data/test/tc/symlink0.rb +1 -1
- data/test/tc/temp.rb +1 -1
- data/test/tc/tempdir.rb +1 -1
- data/test/tc/testcase.rb +7 -1
- metadata +14 -8
- data/lib/rio/matchcolumns.rb +0 -266
- data/lib/rio/rangemath.rb +0 -44
data/lib/rio/doc/INTRO.rb
CHANGED
@@ -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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
allows many application level IO tasks to be accomplished in line or
|
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
|
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
|
-
|
62
|
-
|
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
|
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
|
77
|
-
create any type of Rio. +rio+ looks at the
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
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
|
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
|
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
|
-
|
218
|
-
configuration variable
|
219
|
-
|
220
|
-
|
221
|
-
|
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
|
224
|
-
of an extension.
|
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
|
238
|
-
They are Rio#dirname=, Rio#filename=, Rio#basename=, and
|
239
|
-
methods replace the part extracted as described
|
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
|
248
|
-
object as well as changing the Rio. This is
|
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
|
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
|
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
|
267
|
-
a Rio is among the arguments the
|
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
|
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
|
288
|
-
These methods create a new Rio using the string created by
|
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
|
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
|
315
|
-
the route to get to/from a Rio. They are based on 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
|
321
|
-
and that this is not a comprehensive
|
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
|
-
|
327
|
-
|
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
|
-
|
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
|
-
|
336
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
354
|
-
|
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
|
-
|
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+, +
|
395
|
+
* +lines+, +skiplines+
|
396
|
+
|
363
397
|
rio('afile').lines(0..9)
|
364
|
-
rio('afile').
|
365
|
-
|
366
|
-
|
367
|
-
|
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+, +
|
414
|
+
* +entries+, +files+, +dirs+, +skipentries+, +skipfiles+, +skipdirs+
|
377
415
|
|
378
416
|
rio('adir').files('*.txt')
|
379
|
-
rio('adir').
|
417
|
+
rio('adir').skipfiles(/^\./)
|
380
418
|
|
381
|
-
These methods select which entries will be returned when iterating
|
382
|
-
Entries are included (+entries+,+files+,+dirs+)
|
383
|
-
match *any* of
|
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
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
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
|
408
|
-
not so much as a test for a files
|
409
|
-
|
410
|
-
|
411
|
-
|
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
|
420
|
-
creating and configuring that
|
421
|
-
the
|
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
|
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
|
426
|
-
operations it is returned as a Rio. For
|
427
|
-
|
428
|
-
returns a
|
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
|
431
|
-
Ruby I/O class are available to the Rio and
|
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
|
-
|
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
|
-
|
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
|
-
|
441
|
-
|
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
|
-
|
444
|
-
*
|
445
|
-
|
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
|
453
|
-
<b>The big exception to this is
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
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
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
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
|
470
|
-
|
471
|
-
|
472
|
-
*
|
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
|
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
|
-
|
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
|
486
|
-
|
487
|
-
the
|
488
|
-
the
|
489
|
-
|
490
|
-
|
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
|
-
|
493
|
-
|
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
|
-
|
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
|
-
|
511
|
-
|
512
|
-
|
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
|
-
|
517
|
-
|
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').
|
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
|
538
|
-
Rio#rename and Rio#rename!. Both of these use
|
539
|
-
between them is the returned
|
540
|
-
|
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
|
546
|
-
Rio#filename=, Rio#basename= and Rio#extname= to
|
547
|
-
when they are used to change a
|
548
|
-
calling Rio#rename with
|
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
|
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,
|
565
|
-
and Rio#delete!. +rm+, +rmdir+ and +rmtree+
|
566
|
-
|
567
|
-
calls
|
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
|
576
|
-
Rio#exist? and Rio#symlink? to check
|
577
|
-
|
578
|
-
|
579
|
-
|
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
|
594
|
-
Rio#symlink differs from File#symlink
|
595
|
-
the Rio's
|
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
|
600
|
-
perspective of 'alink', 'adir/afile'
|
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
|
605
|
-
|
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
|
608
|
-
This is done for consistency with the
|
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
|
618
|
-
expects an IO. While Rio is not and is not
|
619
|
-
|
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
|
622
|
-
cause the most incompatibility, is its automatic
|
623
|
-
automatic closing use
|
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
|
-
|
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
|
636
|
-
this is a reasonable thing to do in many cases,
|
637
|
-
To turn Rio's automatic closing on end
|
638
|
-
be turned back on via
|
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
|
645
|
-
implication that may be surprising at first. A Rio starts life
|
646
|
-
much more than a string. When one of its read methods
|
647
|
-
input stream. When the stream is closed, it
|
648
|
-
that when reading from a Rio, the
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
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
|
682
|
-
input or output methed is called. For output
|
683
|
-
|
684
|
-
|
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
|
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
|
696
|
-
the mode specified in the +mode+ method will be
|
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
|
699
|
-
This also will override all of Rio's automatic
|
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
|
705
|
-
and writing comma-separated-value files. Normally
|
706
|
-
identical to <tt>(no)lines</tt> because
|
707
|
-
specify the record-type,
|
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
|
713
|
-
selected using Rio#lines. Rio returns records
|
714
|
-
|
715
|
-
+records+ is the
|
716
|
-
|
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.
|
726
|
-
rio('f.csv').csv.
|
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
|
733
|
-
'out' Rio causes it to treat an array written
|
734
|
-
|
735
|
-
|
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+
|
739
|
-
+to_a+ method which will parse it into an array of
|
740
|
-
when a record is returned using
|
741
|
-
|
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
|
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
|
756
|
-
copy operators
|
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').
|
917
|
+
rio('colonsep').contents #==>"h0:h1\nf0:f1\n"
|
760
918
|
|
761
|
-
Rio provides two methods for selecting fields from CSV records in a
|
762
|
-
to that provided for selecting lines -- Rio#columns and
|
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
|
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').
|
934
|
+
rio('out').contents #==>"h0,h1\nf0,f1\n"
|
775
935
|
|
776
936
|
|
777
937
|
---
|