rio 0.3.3 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
@@ -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
|
-
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
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
|
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#
|
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.
|
144
|
-
# the same as <tt>ario.
|
150
|
+
# type <tt>ario.skiprecords(*args)</tt> is effectively
|
151
|
+
# the same as <tt>ario.skiplines(*args)</tt>.
|
145
152
|
#
|
146
|
-
# rio('afile').
|
147
|
-
# rio('afile').
|
148
|
-
# rio('afile').
|
149
|
-
# rio('afile').chomp.
|
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
|
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>
|
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
|
-
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
169
|
-
#
|
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').
|
172
|
-
# rio('afile').
|
173
|
-
# rio('afile').
|
174
|
-
# rio('afile').chomp.
|
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
|
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#
|
189
|
-
# reasonable. In the
|
190
|
-
def
|
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').
|
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
|