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
@@ -0,0 +1,355 @@
1
+ #--
2
+ # ===============================================================================
3
+ # Copyright (c) 2005, Christopher Kleckner
4
+ # All rights reserved
5
+ #
6
+ # This file is part of the Rio library for ruby.
7
+ #
8
+ # Rio is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Rio is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Rio; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ # ===============================================================================
22
+ #++
23
+ #
24
+ # To create the documentation for Rio run the command
25
+ # rake rdoc
26
+ # from the distribution directory. Then point your browser at the 'doc/rdoc' directory.
27
+ #
28
+ # Suggested Reading
29
+ # * RIO::Doc::SYNOPSIS
30
+ # * RIO::Doc::INTRO
31
+ # * RIO::Doc::HOWTO
32
+ # * RIO::Rio
33
+ #
34
+ # <b>Rio is pre-alpha software.
35
+ # The documented interface and behavior is subject to change without notice.</b>
36
+
37
+
38
+ module RIO
39
+ class Rio
40
+ # Grande Directory Selection Method
41
+ #
42
+ # Sets the rio to return directories. _args_ can be used to select which directories are returned.
43
+ # ario.files(*args) do |f|
44
+ # f.directory? #=> true
45
+ # end
46
+ # No aguments selects all directories.
47
+ # if _args_ are:
48
+ # Regexp:: selects matching directories
49
+ # glob:: selects matching directories
50
+ # Proc:: called for each directory. the directory is processed unless the proc returns false
51
+ # Symbol:: sent to each directory. Each directory is processed unless the symbol returns false
52
+ #
53
+ # If a block is given, behaves like <tt>ario.dirs(*args).each(&block)</tt>
54
+ #
55
+ # See also Rio#files, Rio#entries, Rio#skipdirs
56
+ #
57
+ # rio('adir').dirs { |frio| ... } # process all directories in 'adir'
58
+ # rio('adir').all.dirs { |frio| ... } # same thing recursively
59
+ # rio('adir').dirs(/^\./) { |frio| ...} # process dot directories
60
+ # rio('adir').dirs[/^\./] # return an array of dot directories
61
+ # rio('adir').dirs[:symlink?] # an array of symlinks to directories
62
+ #
63
+ def dirs(*args,&block) target.dirs(*args,&block); self end
64
+
65
+ # Grande Directory Exclude Method
66
+ #
67
+ # If no args are provided selects anything but directories.
68
+ # ario.skipdirs do |el|
69
+ # el.directory? #=> false
70
+ # end
71
+ # If args are provided, sets the rio to select directories as with Rio#dirs, but the arguments are
72
+ # used to determine which directories will *not* be processed
73
+ #
74
+ # If a block is given behaves like
75
+ # ario.skipdirs(*args).each(&block)
76
+ #
77
+ # See Rio#dirs
78
+ #
79
+ # rio('adir').skipdirs { |ent| ... } # iterate through everything except directories
80
+ # rio('adir').skipdirs(/^\./) { |drio| ... } # iterate through directories, skipping dot directories
81
+ #
82
+ #
83
+ def skipdirs(*args,&block) target.skipdirs(*args,&block); self end
84
+
85
+
86
+ # Grande Directory Entry Selection Method
87
+ #
88
+ # No aguments selects all entries.
89
+ #
90
+ # if +args+ are:
91
+ # Regexp:: selects matching entries
92
+ # glob:: selects matching entries
93
+ # Proc:: called for each entry. the entry is processed unless the proc returns false
94
+ # Symbol:: sent to each entry. Each entry is processed unless the symbol returns false
95
+ #
96
+ # If a block is given, behaves like <tt>ario.etries(*args).each(&block)</tt>
97
+ #
98
+ # See also Rio#files, Rio#dirs, Rio#skipentries
99
+ #
100
+ # rio('adir').entries { |frio| ... } # process all entries in 'adir'
101
+ # rio('adir').all.entries { |frio| ... } # same thing recursively
102
+ # rio('adir').entries(/^\./) { |frio| ...} # process entries starting with a dot
103
+ # rio('adir').entries[/^\./] # return an array of all entries starting with a dot
104
+ # rio('adir').entries[:symlink?] # an array of symlinks in 'adir'
105
+ #
106
+ def entries(*args,&block) target.entries(*args,&block); self end
107
+
108
+ # Grande Directory Entry Rejection Method
109
+ #
110
+ # No aguments rejects all entries.
111
+ #
112
+ # Behaves like Rio#entries, except that matching entries are excluded.
113
+ #
114
+ def skipentries(*args,&block) target.skipentries(*args,&block); self end
115
+
116
+
117
+ # Grande File Selection Method
118
+ #
119
+ # Configures the rio to process files. +args+ can be used to select which files are returned.
120
+ # ario.files(*args) do |f|
121
+ # f.file? #=> true
122
+ # end
123
+ # No aguments selects all files.
124
+ #
125
+ # +args+ may be zero or more of the following:
126
+ #
127
+ # Regexp:: selects matching files
128
+ # String:: treated as a glob, and selects matching files
129
+ # Proc:: called for each file. the file is processed unless the proc returns false
130
+ # Symbol:: sent to each file. Each file is processed unless the symbol returns false
131
+ #
132
+ # +files+ returns the Rio which called it. This might seem counter-intuitive at first.
133
+ # One might reasonably assume that
134
+ # rio('adir').files('*.rb')
135
+ # would return files. It does not. It configures the rio to return files and returns
136
+ # the Rio. This enables chaining for further configuration so constructs like
137
+ # rio('adir').all.files('*.rb').norecurse('.svn')
138
+ # are possible.
139
+ #
140
+ # If a block is given, behaves like
141
+ # ario.files(*args).each
142
+ #
143
+ #
144
+ # See also Rio#dirs, Rio#entries, Rio#skipfiles
145
+ #
146
+ # rio('adir').files { |frio| ... } # process all files in 'adir'
147
+ # rio('adir').all.files { |frio| ... } # same thing recursively
148
+ # rio('adir').files('*.rb') { |frio| ...} # process .rb files
149
+ # rio('adir').files['*.rb'] # return an array of .rb files
150
+ # rio('adir').files[/\.rb$/] # same thing using a regular expression
151
+ # rio('adir').files[:symlink?] # an array of symlinks to files
152
+ # rio('adir').files >> rio('other_dir') # copy files to 'other_dir'
153
+ # rio('adir').files('*.rb') >> rio('other_dir') # only copy .rb files
154
+ #
155
+ # For Rios that refer to files, <tt>files(*args)</tt> causes the file to be processed only if
156
+ # it meets the criteria specified by the args.
157
+ #
158
+ # rio('afile.z').files['*.z'] #=> [rio('afile.z')]
159
+ # rio('afile.q').files['*.z'] #=> []
160
+ #
161
+ # === Example Problem
162
+ #
163
+ # Fill the array +ruby_progs+ with all ruby programs in a directory and its subdirectories,
164
+ # skipping those in _subversion_ (.svn) directories.
165
+ #
166
+ # ruby_progs = []
167
+ #
168
+ # For the purposes of this problem, a Ruby program is defined as a file ending with .rb or a file
169
+ # that is executable and whose shebang line contains 'ruby':
170
+ #
171
+ # is_ruby_exe = proc{ |f| f.executable? and f.gets =~ /^#!.+ruby/ }
172
+ #
173
+ # ==== Solution 1. Use the subscript operator.
174
+ #
175
+ # ruby_progs = rio('adir').norecurse('.svn').files['*.rb',is_ruby_exe]
176
+ #
177
+ # Explanation:
178
+ #
179
+ # 1. Create the Rio
180
+ #
181
+ # Create a Rio for a directory
182
+ # rio('adir')
183
+ #
184
+ # 2. Configure the Rio
185
+ #
186
+ # Specify recursion and that '.svn' directories should not be included.
187
+ # rio('adir').norecurse('.svn')
188
+ # Select files
189
+ # rio('adir').norecurse('.svn').files
190
+ # Limit to files ending with '.rb'
191
+ # rio('adir').norecurse('.svn').files('*.rb')
192
+ # Also allow files for whom +is_ruby_exe+ returns true
193
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe)
194
+ #
195
+ # 3. Do the I/O
196
+ #
197
+ # Return an array rather than iterating thru them
198
+ # ruby_progs = rio('adir').norecurse('.svn').files['*.rb',is_ruby_exe]
199
+ #
200
+ # ==== Solution 2. Use the copy-to operator
201
+ #
202
+ # rio('adir').files('*.rb',is_ruby_exe).norecurse('.svn') > ruby_progs
203
+ #
204
+ # Explanation:
205
+ #
206
+ # 1. Create the Rio
207
+ #
208
+ # Create a Rio for a directory
209
+ # rio('adir')
210
+ #
211
+ # 2. Configure the Rio
212
+ #
213
+ # Select only files
214
+ # rio('adir').files
215
+ # Limit to files ending with '.rb'
216
+ # rio('adir').files('*.rb')
217
+ # Also allow files for whom +is_ruby_exe+ returns true
218
+ # rio('adir').files('*.rb',is_ruby_exe)
219
+ # Specify recursion and that '.svn' directories should not be included.
220
+ # rio('adir').files('*.rb',is_ruby_exe).norecurse('.svn')
221
+ #
222
+ # 3. Do the I/O
223
+ #
224
+ # Copy the Rio to ruby_progs
225
+ # rio('adir').files('*.rb',is_ruby_exe).norecurse('.svn') > ruby_progs
226
+ #
227
+ # ==== Example Discussion
228
+ #
229
+ # Note that the only difference between Step 2 of Solution 1 and that of Solution 2 is
230
+ # the order of the configuration methods. Step 2 of Solution 1 would have worked equally
231
+ # well:
232
+ #
233
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe) > ruby_progs
234
+ #
235
+ # Furthermore if our problem were changed slightly and instead of having our results
236
+ # ending up in an array, we wished to iterate through them, we could use:
237
+ #
238
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe) { |ruby_prog_rio| ... }
239
+ #
240
+ # Note the similarities. In fact, solution 1 could have been written:
241
+ #
242
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe).to_a
243
+ # or
244
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe)[]
245
+ #
246
+ # Passing the arguments for +files+ to the subscript operator is syntactic sugar.
247
+ # The subscript operator does not really take any arguments of its own. It always
248
+ # passes them to the most recently called of the grande selection methods (or the
249
+ # default selection method, if none have been called). So,
250
+ #
251
+ # rio('adir').files['*.rb']
252
+ # is a shortcut for
253
+ # rio('adir').files('*.rb').to_a
254
+ #
255
+ # rio('adir')['*.rb']
256
+ # is a shortcut for
257
+ # rio('adir').entries('*.rb').to_a
258
+ #
259
+ # rio('afile').lines[0..10]
260
+ # is a shortcut for
261
+ # rio('afile').lines(0..10).to_a
262
+ #
263
+ # And so on.
264
+ #
265
+ #
266
+ #
267
+ def files(*args,&block) target.files(*args,&block); self end
268
+
269
+ # Grande File Exclude Method
270
+ #
271
+ # If no args are provided selects anything but files.
272
+ # ario.skipfiles do |el|
273
+ # el.file? #=> false
274
+ # end
275
+ # If args are provided, sets the rio to select files as with Rio#files, but the arguments are
276
+ # used to determine which files will *not* be processed
277
+ #
278
+ # If a block is given behaves like <tt>ario.skipfiles(*args).each(&block)</tt>
279
+ #
280
+ # See Rio#files
281
+ #
282
+ # rio('adir').skipfiles { |ent| ... } # iterate through everything except files
283
+ # rio('adir').skipfiles('*~') { |frio| ... } # iterate through files, skipping those ending with a tilde
284
+ #
285
+ #
286
+ def skipfiles(*args,&block) target.skipfiles(*args,&block); self end
287
+
288
+
289
+ # Returns +true+ if the rio is in +all+ (recursive) mode. See Rio#all
290
+ #
291
+ # adir = rio('adir').all.dirs
292
+ # adir.all? # true
293
+ # adir.each do |subdir|
294
+ # subdir.all? # true
295
+ # end
296
+ #
297
+ # rio('adir').all? # false
298
+ #
299
+ def all?() target.all?() end
300
+
301
+
302
+ # Grande Directory Recursion Method
303
+ #
304
+ # Sets the Rio to all mode (recursive)
305
+ #
306
+ # When called with a block, behaves as if all.each(&block) had been called
307
+ #
308
+ # +all+ causes subsequent calls to +files+ or +dirs+ to be applied recursively
309
+ # to subdirectories
310
+ #
311
+ # rio('adir').all.files('*.[ch]').each { |file| ... } # process all c language source files in adir
312
+ # # and all subdirectories of adir
313
+ # rio('adir').all.files(/\.[ch]$/) { |file| ... } # same as above
314
+ # rio('adir').files("*.[ch]").all { |file| ... } # once again
315
+ # rio('adir').all.files["*.[ch]"] # same, but return an array instead of iterating
316
+ #
317
+ def all(arg=true,&block) target.all(arg,&block); self end
318
+
319
+
320
+ # Grande Directory Recursion Selection Method
321
+ #
322
+ # Sets the Rio to recurse into directories like Rio#all. If no args are provided behaves like Rio#all.
323
+ # If args are provided, they are processed like Rio#dirs, to select which subdirectories should
324
+ # be recursed into. Rio#recurse always implies Rio#all.
325
+ #
326
+ # +args+ may be one or more of:
327
+ # Regexp:: recurse into matching subdirectories
328
+ # glob:: recurse into matching subdirectories
329
+ # Proc:: called for each directory. The directory is recursed into unless the proc returns false
330
+ # Symbol:: sent to each directory. Each directory is recursed into unless the symbol returns false
331
+ #
332
+ # If a block is given, behaves like <tt>ario.recurse(*args).each(&block)</tt>
333
+ #
334
+ # See also Rio#norecurse, Rio#all, Rio#dirs
335
+ #
336
+ # rio('adir').recurse('test*') { |drio| ... } # process all entries and all entries in subdirectories
337
+ # # starting with 'test' -- recursively
338
+ #
339
+ def recurse(*args,&block) target.recurse(*args,&block); self end
340
+
341
+
342
+ # Grande Directory Recursion Exclude Method
343
+ #
344
+ # Sets the Rio to recurse into directories like Rio#all. If no args are provided, no
345
+ # directories will be recursed into. If args are provided, behaves like Rio#recurse, except
346
+ # that matching directories will *not* be recursed into
347
+ #
348
+ # rio('adir').norecurse('.svn') { |drio| ... } # recurse, skipping subversion directories
349
+ #
350
+ def norecurse(*args,&block) target.norecurse(*args,&block); self end
351
+
352
+
353
+ end
354
+ end
355
+
@@ -42,12 +42,21 @@ module RIO
42
42
  #
43
43
  # If called with a block behaves as if lines(*args).each(&block) had been called
44
44
  #
45
+ # +lines+ returns the Rio which called it. This might seem counter-intuitive at first.
46
+ # One might reasonably assume that
47
+ # rio('adir').lines(0..10)
48
+ # would return lines. It does not. It configures the rio to return lines and returns
49
+ # the Rio. This enables chaining for further configuration so constructs like
50
+ # rio('afile').lines(0..10).skiplines(/::/)
51
+ # are possible.
52
+ #
45
53
  # If args are provided they may be one or more of the following:
46
54
  # Regexp:: any matching record will be processed
47
55
  # Range:: specifies a range of records (zero-based) to be included
48
56
  # Integer:: interpreted as a one element range of lines to be processed
49
57
  # Proc:: a proc which will be called for each record, records are included unless nil or false is returned
50
58
  # Symbol:: a symbol which will _sent_ to each record, records are included unless nil or false is returned
59
+ # Array:: an array of other selectors. records are selected unless any of the matches fail.
51
60
  #
52
61
  # rio('f.txt').lines(/^\s*#/) { |line| ... } # iterate over comment-only lines
53
62
  # rio('f.txt').lines(/^\s*#/).each { |line| ... } # same as above
@@ -94,16 +103,12 @@ module RIO
94
103
  # and extensions such as Rio#csv.
95
104
  #
96
105
  # If args are provided they may be one or more of the following:
97
- # [Regexp]
98
- # any matching record will be iterated over by Rio#each or returned by Rio#getrec
99
- # [Integer]
100
- # specifies a record-number (zero-based) to be iterated over by Rio#each or returned by Rio#getrec
101
- # [Range]
102
- # specifies a range of records (zero-based) to included in the iteration
103
- # [Proc]
104
- # a proc which will be called for each record, records are included unless nil or false is returned
105
- # [Symbol]
106
- # a symbol which will _sent_ to each record, records are included unless nil or false is returned
106
+ # Regexp:: any matching record will be iterated over by Rio#each or returned by Rio#getrec
107
+ # Integer:: specifies a record-number (zero-based) to be iterated over by Rio#each or returned by Rio#getrec
108
+ # Range:: specifies a range of records (zero-based) to included in the iteration
109
+ # Proc:: a proc which will be called for each record, records are included unless nil or false is returned
110
+ # Symbol:: a symbol which will _sent_ to each record, records are included unless nil or false is returned
111
+ # Array:: an array of any of above. All must match for a line to be included
107
112
  #
108
113
  # Note in the following examples that since +lines+ is the default <tt>ario.records(*args)</tt>
109
114
  # is effectively the same as <tt>ario.lines(*args)</tt>.
@@ -111,23 +116,24 @@ module RIO
111
116
  # rio('afile').records(0) { |line| ... } # iterate over the first line of 'afile'
112
117
  # rio('afile').records(0,5..7)) { |line| ... } # iterate over lines 0,5,6 and 7
113
118
  # rio('afile').records(/Zippy/) { |line| ... } # iterate over all lines containing 'Zippy'
114
- # rio('afile').lines(0,/^\s*#/) { |line| ... } # iterate over the first line and comment lines
115
- # rio('afile').records(0,/^\s*#/) { |line| ... } # same thing
116
- # rio('afile').lines(proc { |rec,rnum,rio| rnum == 0 || rec =~ /^\s*#/ }) { |line| ... } # same thing
117
- # rio('afile').chomp.lines(proc { |rec,rnum,rio| rec.size > 0 }) { |line| ... } # non-empty lines
118
- # # return array containing line 0, all comment lines and any line containing the filename of the Rio
119
- # rio('afile').lines[0,/^\s*#/,proc { |rec,rnum,ario| rec =~ /#{ario.filename}/ }]
120
119
  #
120
+ #
121
+ # rio('f.csv').puts!(["h0,h1","f0,f1"]) # Create f.csv
122
+ #
123
+ # rio('f.csv').csv.records[] #==>[["h0", "h1"], ["f0", "f1"]]
124
+ # rio('f.csv').csv.lines[] #==>["h0,h1\n", "f0,f1\n"]
125
+ # rio('f.csv').csv.records[0] #==>[["h0", "h1"]]
121
126
  #
122
127
  def records(*args,&block) target.records(*args,&block); self end
123
128
 
124
129
  # Specifies records which should *not* be iterated through by Rio#each or returned by Rio#getrec
125
130
  #
126
- # If called with a block behaves as if norecords(*args).each(&block) had been called
131
+ # If called with a block behaves as if <tt>skiprecords(*args).each(&block)</tt>
132
+ # had been called
127
133
  #
128
134
  # Returns the Rio
129
135
  #
130
- # See also Rio#records, Rio#nolines, Rio#lines
136
+ # See also Rio#records, Rio#skiplines, Rio#lines
131
137
  #
132
138
  # If no args are provided, no records are rejected. What constitutes a record is affected by Rio#lines,Rio#bytes,
133
139
  # and extensions such as Rio#csv.
@@ -138,22 +144,23 @@ module RIO
138
144
  # Range:: specifies a range of records (zero-based) to be excluded
139
145
  # Proc:: a proc which will be called for each record, records are excluded unless nil or false is returned
140
146
  # Symbol:: a symbol which will _sent_ to each record, records are excluded unless nil or false is returned
147
+ # Array:: an array of any of the above, all of which must match for the array to match.
141
148
  #
142
149
  # Note in the following examples that since +lines+ is the default record
143
- # type <tt>ario.norecords(*args)</tt> is effectively
144
- # the same as <tt>ario.nolines(*args)</tt>.
150
+ # type <tt>ario.skiprecords(*args)</tt> is effectively
151
+ # the same as <tt>ario.skiplines(*args)</tt>.
145
152
  #
146
- # rio('afile').norecords(0) { |line| ... } # iterate over all but the first line of 'afile'
147
- # rio('afile').norecords(0,5..7)) { |line| ... } # don't iterate over lines 0,5,6 and 7
148
- # rio('afile').norecords(/Zippy/) { |line| ... } # skip all lines containing 'Zippy'
149
- # rio('afile').chomp.nolines(:empty?) { |line| ... } # skip empty lines
153
+ # rio('afile').skiprecords(0) { |line| ... } # iterate over all but the first line of 'afile'
154
+ # rio('afile').skiprecords(0,5..7)) { |line| ... } # don't iterate over lines 0,5,6 and 7
155
+ # rio('afile').skiprecords(/Zippy/) { |line| ... } # skip all lines containing 'Zippy'
156
+ # rio('afile').chomp.skiplines(:empty?) { |line| ... } # skip empty lines
150
157
  #
151
- def norecords(*args,&block) target.norecords(*args,&block); self end
158
+ def skiprecords(*args,&block) target.skiprecords(*args,&block); self end
152
159
 
153
160
  # Sets the Rio to read lines and specifies lines which should *not* be iterated through by Rio#each or
154
161
  # returned by Rio#getrec
155
162
  #
156
- # If called with a block behaves as if <tt>nolines(*args).each(&block)</tt> had been called
163
+ # If called with a block behaves as if <tt>skiplines(*args).each(&block)</tt> had been called
157
164
  #
158
165
  # Returns the Rio
159
166
  #
@@ -162,32 +169,33 @@ module RIO
162
169
  # If no args are provided, no lines are rejected.
163
170
  #
164
171
  # If args are provided they may be one or more of the following:
165
- # [Regexp] any matching line will not be processed
166
- # [Integer] specifies a line-number (zero-based) to be skipped
167
- # [Range] specifies a range of lines (zero-based) to be excluded
168
- # [Proc] a proc which will be called for each line, lines are excluded unless nil or false is returned
169
- # [Symbol] a symbol which will _sent_ to each line, lines are excluded unless nil or false is returned
172
+ # Regexp:: any matching line will not be processed
173
+ # Integer:: specifies a line-number (zero-based) to be skipped
174
+ # Range:: specifies a range of lines (zero-based) to be excluded
175
+ # Proc:: a proc which will be called for each line, lines are excluded unless nil or false is returned
176
+ # Symbol:: a symbol which will _sent_ to each line, lines are excluded unless nil or false is returned
177
+ # Array:: an array of any of above. All must match for a line to be included
170
178
  #
171
- # rio('afile').nolines(0) { |line| ... } # iterate over all but the first line of 'afile'
172
- # rio('afile').nolines(0,5..7)) { |line| ... } # don't iterate over lines 0,5,6 and 7
173
- # rio('afile').nolines(/Zippy/) { |line| ... } # skip all lines containing 'Zippy'
174
- # rio('afile').chomp.nolines(:empty?) { |line| ... } # skip empty lines
179
+ # rio('afile').skiplines(0) { |line| ... } # iterate over all but the first line of 'afile'
180
+ # rio('afile').skiplines(0,5..7)) { |line| ... } # don't iterate over lines 0,5,6 and 7
181
+ # rio('afile').skiplines(/Zippy/) { |line| ... } # skip all lines containing 'Zippy'
182
+ # rio('afile').chomp.skiplines(:empty?) { |line| ... } # skip empty lines
175
183
  #
176
- def nolines(*args,&block) target.nolines(*args,&block); self end
184
+ def skiplines(*args,&block) target.skiplines(*args,&block); self end
177
185
 
178
186
 
179
187
 
180
188
  # Sets the Rio to read rows and specifies rows which should be iterated through
181
- # by Rio#each or returned by Rio#getrec
189
+ # by Rio#each or returned by Rio#getrec.
182
190
  # Rio#rows is intended for use by extensions, where the concept of a row is reasonable.
183
- # In the absensence of an extension behaves like Rio#records
191
+ # In the absensence of an extension behaves like Rio#records.
184
192
  def rows(*args,&block) target.rows(*args,&block); self end
185
193
 
186
194
  # Sets the Rio to read rows and specifies lines which should *not* be iterated
187
195
  # through by Rio#each or returned by Rio#getrec
188
- # Rio#norows is intended for use by extensions, where the concept of a row is
189
- # reasonable. In the absensence of an extension behaves like Rio#norecords
190
- def norows(*args,&block) target.norows(*args,&block); self end
196
+ # Rio#skiprows is intended for use by extensions, where the concept of a row is
197
+ # reasonable. In the absence of an extension behaves like Rio#skiprecords
198
+ def skiprows(*args,&block) target.skiprows(*args,&block); self end
191
199
 
192
200
  # Sets the implicit output mode to 'a'.
193
201
  #
@@ -383,7 +391,7 @@ module RIO
383
391
  # dest.close # must be explicitly closed
384
392
  #
385
393
  # dest = rio('destfile')
386
- # dest.print(rio('srcfile').slurp)
394
+ # dest.print(rio('srcfile').contents)
387
395
  # dest.closed? #=> false (Rio#print is not a copy operator)
388
396
  # dest.close
389
397
  #
@@ -520,6 +528,25 @@ module RIO
520
528
  def chomp(arg=true,&block) target.chomp(arg,&block); self end
521
529
 
522
530
 
531
+ # Queries the Rio's strip-mode.
532
+ # See #strip.
533
+ #
534
+ def strip?() target.strip?() end
535
+
536
+
537
+ # Sets the Rio to strip lines and returns the Rio
538
+ #
539
+ # When called with a block, behaves as if strip.each(&block) had been called
540
+ #
541
+ # +strip+ causes lines returned by each, to_a, readlines, readline, gets, each_line etc.
542
+ # to be stripped with String#strip before iterated over or assigned
543
+ #
544
+ # ans = rio(?-).print("A Prompt> ").strip.gets # prompt the user
545
+ #
546
+ # See also #chomp
547
+ def strip(arg=true,&block) target.strip(arg,&block); self end
548
+
549
+
523
550
  # Sets the Rio to gzip mode.
524
551
  # ario.gzip #=> ario
525
552
  # If applied to a Rio that is being read from Reads
@@ -562,52 +589,6 @@ module RIO
562
589
  #def outputmode?() target.outputmode?() end
563
590
 
564
591
 
565
- # Sets the 'sync-mode' of the underlying IO using IO#sync=
566
- # ario.sync(boolean=true,&block) => ario
567
- # Sets the Rio so that its 'sync mode' will be set to +true+ or +false+ when opened, or set
568
- # it immediatly if already open. When sync mode is
569
- # true, all output is immediately flushed to the underlying operating
570
- # system and is not buffered internally. Returns the rio. See
571
- # also Rio#fsync, Rio#nosync, Rio#sync?.
572
- #
573
- # If a block is given behaves like <tt>ario.sync(arg).each(&block)</tt>
574
- #
575
- # f = rio("testfile").sync.puts("Hello World")
576
- # f.sync? # => true
577
- #
578
- def sync(arg=true,&block) target.sync(arg,&block); self end
579
-
580
- # Similar to IO#sync= false
581
- # ario.nosync(&block) => ario
582
- # Sets the Rio so that its 'sync mode' will be set to +false+ when opened, or set
583
- # it immediatly if already open. When sync mode is
584
- # true, all output is immediately flushed to the underlying operating
585
- # system and is not buffered internally. Returns the rio. See
586
- # also Rio#fsync, Rio#sync, Rio#sync?.
587
- #
588
- # If a block is given behaves like <tt>ario.nosync.each(&block)</tt>
589
- #
590
- # f = rio("testfile").sync.puts("Hello World")
591
- # f.sync? # => true
592
- # f.nosync
593
- # f.sync? # => false
594
- #
595
- def nosync(arg=false,&block) target.nosync(arg,&block); self end
596
-
597
- # Query the current 'sync mode' with IO#sync
598
- # ario.sync? => true or false
599
- # Returns the current ``sync mode'' of _ario_. When sync mode is true,
600
- # all output is immediately flushed to the underlying operating
601
- # system and is not buffered by Ruby internally. See also +Rio#fsync+,
602
- # Rio#sync, Rio#nosync
603
- #
604
- # f = rio("testfile")
605
- # f.sync? #=> false
606
- #
607
- def sync?() target.sync?() end
608
-
609
-
610
-
611
592
 
612
593
  end
613
594
  end