rio 0.3.8 → 0.3.9
Sign up to get free protection for your applications and to get access to all the features.
- data/README +18 -12
- data/Rakefile +57 -87
- data/build_doc.rb +19 -17
- data/doc/ANNOUNCE +3 -32
- data/doc/RELEASE_NOTES +4 -5
- data/doc/RIOIS +215 -0
- data/doc/generators/template/html/rio.css +428 -0
- data/doc/generators/template/html/rio.rb +18 -389
- data/doc/generators/template/html/ugly.rb +130 -0
- data/doc/pkg_def.rb +66 -0
- data/ex/catcsv.rb +64 -0
- data/ex/colx.rb +8 -0
- data/ex/findinruby +15 -0
- data/ex/findruby +14 -0
- data/ex/passwd_report.rb +8 -0
- data/ex/prompt.rb +25 -0
- data/ex/rgb.txt.gz +0 -0
- data/ex/riocat +42 -0
- data/ex/riogunzip +31 -0
- data/ex/riogzip +24 -0
- data/ex/rioprompt.rb +10 -0
- data/ex/targz2zip +17 -0
- data/ex/tonl +10 -0
- data/lib/rio.rb +16 -10
- data/lib/rio/abstract_method.rb +3 -4
- data/lib/rio/argv.rb +3 -4
- data/lib/rio/arycopy.rb +3 -4
- data/lib/rio/assert.rb +3 -4
- data/lib/rio/base.rb +3 -4
- data/lib/rio/callstr.rb +3 -4
- data/lib/rio/const.rb +3 -4
- data/lib/rio/construct.rb +3 -4
- data/lib/rio/constructor.rb +12 -8
- data/lib/rio/context.rb +15 -30
- data/lib/rio/context/autoclose.rb +3 -4
- data/lib/rio/context/copying.rb +3 -4
- data/lib/rio/context/cxx.rb +3 -4
- data/lib/rio/context/dir.rb +3 -4
- data/lib/rio/context/gzip.rb +3 -4
- data/lib/rio/context/methods.rb +16 -5
- data/lib/rio/context/skip.rb +3 -4
- data/lib/rio/context/stream.rb +42 -5
- data/lib/rio/cp.rb +7 -7
- data/lib/rio/def.rb +3 -4
- data/lib/rio/dir.rb +3 -4
- data/lib/rio/doc.rb +4 -5
- data/lib/rio/doc/EXAMPLES.rb +299 -0
- data/lib/rio/doc/HOWTO.rb +3 -4
- data/lib/rio/doc/INTRO.rb +86 -105
- data/lib/rio/doc/OPTIONAL.rb +4 -5
- data/lib/rio/doc/SYNOPSIS.rb +7 -6
- data/lib/rio/entrysel.rb +21 -23
- data/lib/rio/exception.rb +3 -4
- data/lib/rio/exception/copy.rb +3 -4
- data/lib/rio/exception/notimplemented.rb +57 -0
- data/lib/rio/exception/notsupported.rb +3 -4
- data/lib/rio/exception/open.rb +3 -4
- data/lib/rio/exception/state.rb +3 -4
- data/lib/rio/ext.rb +47 -13
- data/lib/rio/ext/csv.rb +4 -5
- data/lib/rio/ext/if.rb +45 -0
- data/lib/rio/ext/mp3info.rb +80 -0
- data/lib/rio/ext/splitlines.rb +253 -0
- data/lib/rio/ext/yaml.rb +9 -5
- data/lib/rio/ext/yaml/doc.rb +133 -0
- data/lib/rio/ext/yaml/tie.rb +149 -0
- data/lib/rio/ext/zipfile.rb +23 -4
- data/lib/rio/ext/zipfile/fs.rb +116 -0
- data/lib/rio/ext/zipfile/rl.rb +251 -0
- data/lib/rio/ext/zipfile/rootdir.rb +117 -0
- data/lib/rio/ext/zipfile/state.rb +161 -0
- data/lib/rio/ext/zipfile/wrap.rb +204 -0
- data/lib/rio/factory.rb +235 -27
- data/lib/rio/file.rb +4 -4
- data/lib/rio/filter.rb +3 -4
- data/lib/rio/filter/closeoneof.rb +3 -4
- data/lib/rio/filter/gzip.rb +9 -4
- data/lib/rio/fs/base.rb +3 -4
- data/lib/rio/fs/impl.rb +4 -5
- data/lib/rio/fs/native.rb +3 -4
- data/lib/rio/fs/stream.rb +3 -4
- data/lib/rio/fs/url.rb +3 -4
- data/lib/rio/ftp/conncache.rb +19 -5
- data/lib/rio/ftp/dir.rb +3 -4
- data/lib/rio/ftp/fs.rb +30 -24
- data/lib/rio/grande.rb +27 -7
- data/lib/rio/handle.rb +3 -4
- data/lib/rio/if.rb +19 -15
- data/lib/rio/if/basic.rb +7 -7
- data/lib/rio/if/csv.rb +5 -6
- data/lib/rio/if/dir.rb +120 -114
- data/lib/rio/if/file.rb +52 -44
- data/lib/rio/if/fileordir.rb +217 -211
- data/lib/rio/if/grande.rb +674 -644
- data/lib/rio/if/grande_entry.rb +321 -313
- data/lib/rio/if/grande_stream.rb +653 -553
- data/lib/rio/if/internal.rb +3 -4
- data/lib/rio/if/path.rb +425 -426
- data/lib/rio/if/rubyio.rb +681 -0
- data/lib/rio/if/string.rb +42 -5
- data/lib/rio/if/temp.rb +3 -4
- data/lib/rio/if/test.rb +245 -238
- data/lib/rio/if/yaml.rb +15 -41
- data/lib/rio/ioh.rb +7 -5
- data/lib/rio/iomode.rb +19 -7
- data/lib/rio/ios/fail.rb +4 -5
- data/lib/rio/ios/generic.rb +4 -5
- data/lib/rio/ios/mode.rb +4 -5
- data/lib/rio/ios/null.rb +6 -7
- data/lib/rio/iowrap.rb +3 -4
- data/lib/rio/kernel.rb +3 -5
- data/lib/rio/local.rb +3 -4
- data/lib/rio/match.rb +3 -4
- data/lib/rio/matchrecord.rb +3 -4
- data/lib/rio/no_warn.rb +3 -4
- data/lib/rio/nullio.rb +3 -4
- data/lib/rio/open3.rb +4 -5
- data/lib/rio/ops/construct.rb +3 -4
- data/lib/rio/ops/create.rb +11 -6
- data/lib/rio/ops/dir.rb +19 -8
- data/lib/rio/ops/either.rb +6 -5
- data/lib/rio/ops/file.rb +3 -4
- data/lib/rio/ops/path.rb +14 -35
- data/lib/rio/ops/stream.rb +3 -4
- data/lib/rio/ops/stream/input.rb +4 -7
- data/lib/rio/ops/stream/output.rb +3 -4
- data/lib/rio/ops/stream/read.rb +6 -5
- data/lib/rio/ops/stream/write.rb +3 -4
- data/lib/rio/ops/symlink.rb +3 -4
- data/lib/rio/path.rb +22 -18
- data/lib/rio/path/reset.rb +4 -5
- data/lib/rio/piper.rb +3 -4
- data/lib/rio/piper/cp.rb +3 -4
- data/lib/rio/prompt.rb +10 -5
- data/lib/rio/rectype.rb +5 -5
- data/lib/rio/rl/base.rb +17 -71
- data/lib/rio/rl/builder.rb +14 -38
- data/lib/rio/rl/chmap.rb +66 -0
- data/lib/rio/rl/fs2url.rb +82 -0
- data/lib/rio/rl/ioi.rb +4 -4
- data/lib/rio/rl/path.rb +44 -122
- data/lib/rio/rl/pathmethods.rb +19 -8
- data/lib/rio/rl/uri.rb +137 -60
- data/lib/rio/rl/withpath.rb +295 -0
- data/lib/rio/scheme/aryio.rb +3 -4
- data/lib/rio/scheme/cmdio.rb +3 -4
- data/lib/rio/scheme/cmdpipe.rb +4 -4
- data/lib/rio/scheme/fd.rb +3 -4
- data/lib/rio/scheme/ftp.rb +7 -7
- data/lib/rio/scheme/http.rb +4 -5
- data/lib/rio/scheme/null.rb +3 -4
- data/lib/rio/scheme/path.rb +3 -4
- data/lib/rio/scheme/stderr.rb +3 -4
- data/lib/rio/scheme/stdio.rb +3 -4
- data/lib/rio/scheme/strio.rb +3 -4
- data/lib/rio/scheme/sysio.rb +3 -4
- data/lib/rio/scheme/tcp.rb +3 -4
- data/lib/rio/scheme/temp.rb +6 -6
- data/lib/rio/state.rb +18 -46
- data/lib/rio/state/error.rb +3 -4
- data/lib/rio/stream.rb +4 -4
- data/lib/rio/stream/base.rb +3 -4
- data/lib/rio/stream/duplex.rb +3 -4
- data/lib/rio/stream/open.rb +3 -8
- data/lib/rio/symantics.rb +3 -4
- data/lib/rio/tempdir.rb +2 -2
- data/lib/rio/to_rio.rb +3 -4
- data/lib/rio/to_rio/all.rb +3 -4
- data/lib/rio/to_rio/array.rb +4 -5
- data/lib/rio/to_rio/io.rb +4 -5
- data/lib/rio/to_rio/object.rb +4 -5
- data/lib/rio/to_rio/string.rb +4 -5
- data/lib/rio/uri/file.rb +41 -5
- data/lib/rio/util.rb +3 -4
- data/lib/rio/version.rb +4 -5
- data/setup.rb +368 -339
- data/test/bin/list_dir.rb +1 -1
- data/test/ftp/anon_misc.rb +13 -1
- data/test/ftp/anon_special.rb +6 -6
- data/test/ftp/anon_write.rb +10 -3
- data/test/ftp/ftp2ftp.rb +2 -2
- data/test/ftp/testdef.rb +9 -6
- data/test/http/all.rb +3 -0
- data/test/http/copy-from-http.rb +140 -0
- data/test/lib/temp_server.rb +44 -0
- data/test/runalltests.rb +3 -1
- data/test/runhttp.rb +12 -0
- data/test/runhttptests.rb +1 -1
- data/test/runtests.rb +41 -3
- data/test/tc/abs.rb +9 -5
- data/test/tc/all.rb +9 -4
- data/test/tc/base.rb +1 -1
- data/test/tc/base2.rb +87 -0
- data/test/tc/{methods.rb → clone.rb} +72 -50
- data/test/tc/closeoncopy.rb +13 -2
- data/test/tc/copy-dir-samevar.rb +91 -0
- data/test/tc/dir_iter.rb +0 -1
- data/test/tc/empty.rb +6 -2
- data/test/tc/expand_path.rb +36 -54
- data/test/tc/ext.rb +42 -18
- data/test/tc/gzip.rb +30 -3
- data/test/tc/likeio.rb +5 -1
- data/test/tc/line_record_row.rb +51 -0
- data/test/tc/noqae.rb +71 -70
- data/test/tc/path_parts.rb +175 -0
- data/test/tc/programs_util.rb +3 -3
- data/test/tc/rename.rb +4 -5
- data/test/tc/riorl.rb +9 -7
- data/test/tc/skip.rb +35 -6
- data/test/tc/skiplines.rb +34 -5
- data/test/tc/split.rb +8 -50
- data/test/tc/splitlines.rb +65 -0
- data/test/tc/splitpath.rb +83 -0
- data/test/tc/testcase.rb +1 -1
- data/test/tc/truncate.rb +39 -0
- data/test/tc/yaml.rb +9 -8
- metadata +261 -207
- data/ChangeLog +0 -1418
- data/VERSION +0 -1
- data/lib/rio/doc/MISC.rb +0 -259
- data/lib/rio/if/stream.rb +0 -680
- data/lib/rio/impl/path.rb +0 -87
- data/test/tc/copy-from-http.rb +0 -89
@@ -0,0 +1,299 @@
|
|
1
|
+
#--
|
2
|
+
# ===============================================================================
|
3
|
+
# Copyright (c) 2005,2006,2007 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
|
+
# ruby build_doc.rb
|
26
|
+
# from the distribution directory.
|
27
|
+
#
|
28
|
+
# Suggested Reading
|
29
|
+
# * RIO::Doc::SYNOPSIS
|
30
|
+
# * RIO::Doc::INTRO
|
31
|
+
# * RIO::Doc::HOWTO
|
32
|
+
# * RIO::Doc::EXAMPLES
|
33
|
+
# * RIO::Rio
|
34
|
+
#
|
35
|
+
|
36
|
+
|
37
|
+
module RIO
|
38
|
+
module Doc
|
39
|
+
=begin rdoc
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
The following examples are provided without comment
|
44
|
+
|
45
|
+
array = rio('afile').readlines
|
46
|
+
|
47
|
+
rio('afile') > rio('acopy')
|
48
|
+
|
49
|
+
ary = rio('afile').chomp.lines[0...10]
|
50
|
+
|
51
|
+
rio('adir').rename.all.files('*.htm') do |file|
|
52
|
+
file.ext = '.html'
|
53
|
+
end
|
54
|
+
|
55
|
+
A basic familiarity with ruby and shell operations should allow a
|
56
|
+
casual reader to guess what these examples will do. How they are being
|
57
|
+
performed may not be what a casual reader might expect. I will
|
58
|
+
explain these example to illustrate the Rio basics.
|
59
|
+
|
60
|
+
For many more examples please read the HOWTO document and the rdoc
|
61
|
+
documentation.
|
62
|
+
|
63
|
+
== Example 1.
|
64
|
+
|
65
|
+
array = rio('afile').readlines
|
66
|
+
|
67
|
+
This uses IO#readlines to read the lines of 'afile' into an array.
|
68
|
+
|
69
|
+
=== Creating a Rio
|
70
|
+
|
71
|
+
Rio extends the module Kernel by adding one function +rio+, which acts
|
72
|
+
as a constructor returning a Rio. This constructor builds a
|
73
|
+
description of the resource the Rio will access (usually a path). It
|
74
|
+
does not open the resource, check for its existance, or do anything
|
75
|
+
except remember its specifcation. _rio_ returns the Rio which can be
|
76
|
+
chained to a Rio method as in this example or stored in a
|
77
|
+
variable. This coud have been written
|
78
|
+
|
79
|
+
ario = rio('afile')
|
80
|
+
array = ario.readlines
|
81
|
+
|
82
|
+
ario = rio('afile')
|
83
|
+
|
84
|
+
In this case the resource specified is a relative path. After the
|
85
|
+
first line the Rio does know or care whether it is a path to a file
|
86
|
+
nor whether it exists. Rio provides many methods that only deal with a
|
87
|
+
resource at this level, much as the standard library classes Pathname
|
88
|
+
and URI. It should be noted at this point that Rio paths stored
|
89
|
+
internally as a URL as specified in RFC 1738 and therefore use slashes
|
90
|
+
as separators. A resource can also be specified without separators,
|
91
|
+
because _rio_ interprets multiple arguments as parts of a path to be
|
92
|
+
joined, and an array as an array of parts to be joined. So the
|
93
|
+
following all specify the same resource.
|
94
|
+
|
95
|
+
rio('adir/afile')
|
96
|
+
rio('adir','afile')
|
97
|
+
rio(%w/adir afile/)
|
98
|
+
|
99
|
+
The rio constructor can be used to specify non-file-system resources,
|
100
|
+
but for this example we will restrict our discussion to paths to
|
101
|
+
entities on file-systems.
|
102
|
+
|
103
|
+
array = ario.readlines
|
104
|
+
|
105
|
+
Now that we have a Rio, we can call one of its methods; in this case
|
106
|
+
_readlines_. This is an example of using a Rio as a proxy for the
|
107
|
+
builtin IO#readlines. Given the method _readlines_, the Rio opens
|
108
|
+
'afile' for reading, calls readlines on the resulting IO object,
|
109
|
+
closes the IO object, and returns the lines read.
|
110
|
+
|
111
|
+
== Example 2
|
112
|
+
|
113
|
+
rio('afile') > rio('acopy')
|
114
|
+
|
115
|
+
This copies the file 'afile' into the file 'acopy'.
|
116
|
+
|
117
|
+
The first things that happen here are the creation of the Rios. As
|
118
|
+
described in Example 1, when created a Rio simply remembers the
|
119
|
+
specifcation of its resource. In this case, a relative path 'afile' on
|
120
|
+
the left and a relative path 'acopy' on the right.
|
121
|
+
|
122
|
+
Next the Rio#> (copy-to) method is called on the 'afile' Rio with the
|
123
|
+
'acopy' Rio as its argument. If that looks like a greater-than
|
124
|
+
operator to you, think Unix shell, with Rios '>' is the copy-to
|
125
|
+
operator.
|
126
|
+
|
127
|
+
Upon seeing the copy-to operator, the Rio has all the information it
|
128
|
+
needs to proceed. It determines that it must be opened for reading,
|
129
|
+
that its argument must be opened for writing, and that it's contents
|
130
|
+
must be copied to the resource referenced by it' argument -- and that
|
131
|
+
is what it does. Then it closes itself and its argument.
|
132
|
+
|
133
|
+
Consider if we had written this example this way.
|
134
|
+
|
135
|
+
afile = rio('afile')
|
136
|
+
acopy = rio('acopy')
|
137
|
+
afile > acopy
|
138
|
+
|
139
|
+
In this case we would still have variables referencing the Rios, and
|
140
|
+
perhaps we would like do things a little differently than described
|
141
|
+
above. Be assured that the selection of mode and automatic closing of
|
142
|
+
files are the default behaviour and can be changed. Say we wanted
|
143
|
+
'afile' to remain open so that we could rewind it and make a second
|
144
|
+
copy, we might do something like this:
|
145
|
+
|
146
|
+
afile = rio('afile').nocloseoneof
|
147
|
+
afile > rio('acopy1')
|
148
|
+
afile.rewind > rio('acopy2')
|
149
|
+
afile.close
|
150
|
+
|
151
|
+
Actually the 'thinking process' of the Rio when it sees a copy-to
|
152
|
+
operator is much more complex than that described above. If its
|
153
|
+
argument had been a rio referencing a directory, it would not have
|
154
|
+
opened itself for reading, but instead used FileUtils#cp to copy
|
155
|
+
itself; if its argument had been a string, its contents would have
|
156
|
+
ended up in the string; If its argument had been an array, its lines
|
157
|
+
would been elements of that array; if its argument had been a socket,
|
158
|
+
the its contents would have been copied to the socket. See the
|
159
|
+
documentation for details.
|
160
|
+
|
161
|
+
== Example 3.
|
162
|
+
|
163
|
+
array = rio('afile').chomp.lines[0...10]
|
164
|
+
|
165
|
+
This fills +array+ with the first ten lines of 'afile', with each line chomped
|
166
|
+
|
167
|
+
The casual observer mentioned above might think that +lines+ returns an array of lines and that this
|
168
|
+
is a simple rewording of <tt>array = rio('afile').readlines[0...10]</tt> or even of
|
169
|
+
<tt>array = File.new('afile').readlines[0...10]</tt>. They would be wrong.
|
170
|
+
|
171
|
+
+chomp+ is a configuration method which turns on chomp-mode and returns the Rio. Chomp-mode causes all
|
172
|
+
line oriented read operations to perform a String#chomp on each line
|
173
|
+
|
174
|
+
=== Reading files
|
175
|
+
|
176
|
+
Rio provides four methods to select which part of the file is read and
|
177
|
+
how the file is divided. They are +lines+, +records+, +rows+ and
|
178
|
+
+bytes+. Briefly, +lines+ specifies that the file should be read line
|
179
|
+
by line and <tt>bytes(n)</tt> specifies that the file should be read
|
180
|
+
in _n_ byte chunks. All four take arguments which can be used to
|
181
|
+
filter lines or chunks in or out. For simple Rios +records+ and +rows+
|
182
|
+
only specify the filter arguments and are provided for use be
|
183
|
+
extensions. For example, the CSV extension returns an array of the
|
184
|
+
columns in a line when +records+ is used. In the absence of an
|
185
|
+
extension +records+ and +rows+ behave like +lines+.
|
186
|
+
|
187
|
+
First lets rewrite our example as:
|
188
|
+
|
189
|
+
array = rio('afile').chomp.lines(0...10).to_a
|
190
|
+
|
191
|
+
The arguments to lines specify which records are to be read.
|
192
|
+
Arguments are interpreted based on their class as follows:
|
193
|
+
* Range - interpreted as a range of record numbers to be read
|
194
|
+
* Integer - interpreted as a one-element range
|
195
|
+
* RegExp - only matching records are processed
|
196
|
+
* Symbol - sent to each record, which is processed unless the result is false or nil
|
197
|
+
* Proc - called for each record, the record is processed unless the return value is false or nil
|
198
|
+
See the documentation for details and examples.
|
199
|
+
|
200
|
+
In our example we have specified the Range (0...10). The +lines+
|
201
|
+
method is just configuring the Rio, it does not trigger any IO
|
202
|
+
operation. The fact that it was called and the arguments it was called
|
203
|
+
with are stored away and the Rio is returned for further configuration
|
204
|
+
or an actual IO operation. When an IO operation is called the Range
|
205
|
+
will be used to limit processing to the first ten records. For
|
206
|
+
example:
|
207
|
+
|
208
|
+
rio('afile').lines(0...10).each { |line| ... } # block will be called for the first 10 records
|
209
|
+
rio('afile').lines(0...10).to_a # the first 10 records will be returned in an array
|
210
|
+
rio('afile').lines(0...10) > rio('acopy') # the first 10 records will be copied to 'acopy'
|
211
|
+
|
212
|
+
"But wait", you say, "In our original example the range was an
|
213
|
+
argument to the subscript operator, not to +lines+". This works
|
214
|
+
because the subscript operator processes its arguments as if they had
|
215
|
+
been arguments to the most-recently-called selection method and then
|
216
|
+
calls +to_a+ on the rio. So our rewrite of the example does precisely
|
217
|
+
the same thing as the original
|
218
|
+
|
219
|
+
The big difference between the original example and the
|
220
|
+
casual-observer's solution is that hers creates an array of the entire
|
221
|
+
contents and only returns the first 10 while the original only puts 10
|
222
|
+
records into the array.
|
223
|
+
|
224
|
+
As a sidenote, Rios also have an optimization that can really help in
|
225
|
+
certain situations. If records are only selected using Ranges, it
|
226
|
+
stops iterating when it is beyond the point where it could possibly
|
227
|
+
ever match. This can make a dramatic difference when one is only
|
228
|
+
interested in the first few lines of very large files.
|
229
|
+
|
230
|
+
== Example 4.
|
231
|
+
|
232
|
+
rio('adir').rename.all.files('*.htm') do |file|
|
233
|
+
file.ext = '.html'
|
234
|
+
end
|
235
|
+
|
236
|
+
This changes the extension of all .htm files below 'adir' to '.html'
|
237
|
+
|
238
|
+
First we create the rio as always.
|
239
|
+
|
240
|
+
Next we process the +rename+ method. When used as it is here --
|
241
|
+
without arguments -- it just turns on rename-mode and returns the Rio.
|
242
|
+
|
243
|
+
+all+ is another configuration method, which causes directories to be
|
244
|
+
processed recursively
|
245
|
+
|
246
|
+
+files+ is another configuration method. In example 3 we used +lines+
|
247
|
+
to select what to process when iterating through a file. +files+ is
|
248
|
+
used to select what to process when iterating through directories. The
|
249
|
+
arguments to +files+ can be the same as those for +lines+ except that
|
250
|
+
Ranges can not be used and globs can.
|
251
|
+
|
252
|
+
In our example, the argument to +files+ is a string which is treated
|
253
|
+
as a glob. As with +lines+, +files+ does not trigger any IO, it just
|
254
|
+
configures the Rio.
|
255
|
+
|
256
|
+
=== There's no action
|
257
|
+
|
258
|
+
The previous examples had something that triggered IO: +readlines+,
|
259
|
+
+to_a+, +each+, <tt>> (copy-to)</tt>. This example does not. This
|
260
|
+
example illustrates Rio's 'implied each'. All the configuration
|
261
|
+
methods will call each for you if a block is given. So, because a
|
262
|
+
block follows the +files+ method, it calls +each+ and passes it the
|
263
|
+
block.
|
264
|
+
|
265
|
+
Let's recap. At this point we have a Rio with a resource specified. We
|
266
|
+
have configured with a couple of modes, 'rename', and 'all', and we
|
267
|
+
have limited the elements we want to process to entries that are files
|
268
|
+
and match the glob '*.htm'. +each+ causes the Rio to open the
|
269
|
+
directory and call the block for each entry that is both a file and
|
270
|
+
matches the glob. It was also configured with +all+,so it descends
|
271
|
+
into subdirectories to find further matches and calles the block for
|
272
|
+
each of them. The argument passed to the block is a Rio referencing
|
273
|
+
the entry on the file-system.
|
274
|
+
|
275
|
+
The _rename_mode_ we set has had no effect on our iteration at all, so why is it there? In general,
|
276
|
+
configuration options that are not applicable to a Rio are silently ignored, however, for directories
|
277
|
+
some of them are passed on to the Rios for each entry when iterating. Since +rename+ is one such option,
|
278
|
+
The example could have been written:
|
279
|
+
|
280
|
+
rio('adir').all.files('*.htm') do |file|
|
281
|
+
file.rename.ext = '.html'
|
282
|
+
end
|
283
|
+
|
284
|
+
The rename-with-no-args method affects the behaviour of the <tt>ext=</tt> option. In this case,
|
285
|
+
setting it for the directory, rather than for each file in the block seems to make the intent
|
286
|
+
of the code more clear, but that is a matter of personal taste. See the documentation for more
|
287
|
+
information on the rename-with-no-args method
|
288
|
+
|
289
|
+
== Suggested Reading
|
290
|
+
* RIO::Doc::SYNOPSIS
|
291
|
+
* RIO::Doc::INTRO
|
292
|
+
* RIO::Doc::HOWTO
|
293
|
+
* RIO::Rio
|
294
|
+
|
295
|
+
=end
|
296
|
+
module EXAMPLES
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
data/lib/rio/doc/HOWTO.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#--
|
2
2
|
# ===============================================================================
|
3
|
-
# Copyright (c) 2005,
|
3
|
+
# Copyright (c) 2005,2006,2007 Christopher Kleckner
|
4
4
|
# All rights reserved
|
5
5
|
#
|
6
6
|
# This file is part of the Rio library for ruby.
|
@@ -23,16 +23,15 @@
|
|
23
23
|
#
|
24
24
|
# To create the documentation for Rio run the command
|
25
25
|
# ruby build_doc.rb
|
26
|
-
# from the distribution directory.
|
26
|
+
# from the distribution directory.
|
27
27
|
#
|
28
28
|
# Suggested Reading
|
29
29
|
# * RIO::Doc::SYNOPSIS
|
30
30
|
# * RIO::Doc::INTRO
|
31
31
|
# * RIO::Doc::HOWTO
|
32
|
+
# * RIO::Doc::EXAMPLES
|
32
33
|
# * RIO::Rio
|
33
34
|
#
|
34
|
-
# <b>Rio is pre-alpha software.
|
35
|
-
# The documented interface and behavior is subject to change without notice.</b>
|
36
35
|
|
37
36
|
|
38
37
|
module RIO
|
data/lib/rio/doc/INTRO.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#--
|
2
2
|
# ===============================================================================
|
3
|
-
# Copyright (c) 2005,
|
3
|
+
# Copyright (c) 2005,2006,2007 Christopher Kleckner
|
4
4
|
# All rights reserved
|
5
5
|
#
|
6
6
|
# This file is part of the Rio library for ruby.
|
@@ -23,16 +23,15 @@
|
|
23
23
|
#
|
24
24
|
# To create the documentation for Rio run the command
|
25
25
|
# ruby build_doc.rb
|
26
|
-
# from the distribution directory.
|
26
|
+
# from the distribution directory.
|
27
27
|
#
|
28
28
|
# Suggested Reading
|
29
29
|
# * RIO::Doc::SYNOPSIS
|
30
30
|
# * RIO::Doc::INTRO
|
31
31
|
# * RIO::Doc::HOWTO
|
32
|
+
# * RIO::Doc::EXAMPLES
|
32
33
|
# * RIO::Rio
|
33
34
|
#
|
34
|
-
# <b>Rio is pre-alpha software.
|
35
|
-
# The documented interface and behavior is subject to change without notice.</b>
|
36
35
|
|
37
36
|
|
38
37
|
module RIO
|
@@ -248,15 +247,15 @@ to the File or URI classes with the return values converted to a Rio.
|
|
248
247
|
==== Creating a Rio from a Rio's component parts.
|
249
248
|
|
250
249
|
The Rio methods for creating a Rio from a Rio's component parts are
|
251
|
-
|
252
|
-
behavior of
|
250
|
+
IF::Path#dirname, IF::Path#filename, IF::Path#basename, and IF::Path#extname. The
|
251
|
+
behavior of IF::Path#basename depends on the setting of the +ext+
|
253
252
|
configuration variable and is different from its counterpart in the
|
254
253
|
File class. The default value of the +ext+ configuration variable is
|
255
254
|
the string returned File#extname. The +ext+ configuration variable can
|
256
|
-
be changed using
|
257
|
-
|
255
|
+
be changed using IF::Path#ext and IF::Path#noext and can be queried using
|
256
|
+
IF::Path#ext?. This value is used by calls to IF::Path#basename.
|
258
257
|
|
259
|
-
|
258
|
+
IF::Path#filename returns the last component of a path, and is basically
|
260
259
|
the same as +basename+ without consideration of an extension.
|
261
260
|
|
262
261
|
rio('afile.txt').basename #=> rio('afile')
|
@@ -271,8 +270,8 @@ the same as +basename+ without consideration of an extension.
|
|
271
270
|
==== Changing a path's component parts.
|
272
271
|
|
273
272
|
Rio also provides methods for changing the component parts of its
|
274
|
-
path. They are
|
275
|
-
|
273
|
+
path. They are IF::Path#dirname=, IF::Path#filename=, IF::Path#basename=, and
|
274
|
+
IF::Path#extname=. These methods replace the part extracted as described
|
276
275
|
above with their argument.
|
277
276
|
|
278
277
|
ario = rio('dirA/dirB/afile.rb')
|
@@ -287,8 +286,8 @@ discussed in the section on Renaming and Moving.
|
|
287
286
|
|
288
287
|
==== Splitting a Rio
|
289
288
|
|
290
|
-
|
291
|
-
that this behavior differs from File#split.)
|
289
|
+
IF::Grande#split (or IF::Path#splitpath) returns an array of Rios, one
|
290
|
+
for each path element. (Note that this behavior differs from File#split.)
|
292
291
|
|
293
292
|
rio('a/b/c').split #=> [rio('a'),rio('b'),rio('c')]
|
294
293
|
|
@@ -307,7 +306,7 @@ constructor will take, the constructor can be used.
|
|
307
306
|
ario = rio('adir')
|
308
307
|
rio(ario,'b') #=> rio('adir/b')
|
309
308
|
|
310
|
-
|
309
|
+
IF::Path#join and IF::Path#/ do the same thing, but the operator version
|
311
310
|
<tt>/</tt> can take only one argument.
|
312
311
|
|
313
312
|
a = rio('a')
|
@@ -315,7 +314,7 @@ Rio#join and Rio#/ do the same thing, but the operator version
|
|
315
314
|
c = a.join(b) #=> rio('a/b')
|
316
315
|
c = a/b #=> rio('a/b')
|
317
316
|
|
318
|
-
The arguments to
|
317
|
+
The arguments to IF::Path#join and IF::Path#/ do not need to be Rios, of course
|
319
318
|
ario = rio('adir')
|
320
319
|
ario/'afile.rb' #=> rio('adir/afile.rb')
|
321
320
|
ario.join('b','c','d') #=> rio('adir/b/c/d')
|
@@ -324,8 +323,8 @@ The arguments to +join+ and <tt>/</tt> do not need to be Rios, of course
|
|
324
323
|
|
325
324
|
==== Manipulating a Rio path by treating it as a string.
|
326
325
|
|
327
|
-
The Rio methods which treat a Rio as a string are
|
328
|
-
and
|
326
|
+
The Rio methods which treat a Rio as a string are IF::String#sub, IF::String#gsub
|
327
|
+
and IF::String#+. These methods create a new Rio using the string created by
|
329
328
|
forwarding the method to the String returned by Rio#to_s.
|
330
329
|
|
331
330
|
ario = rio('dirA/dirB/afile') + '-1.1.1' # rio('dirA/dirB/afile-1.1.1')
|
@@ -334,8 +333,8 @@ forwarding the method to the String returned by Rio#to_s.
|
|
334
333
|
|
335
334
|
==== Creating a Rio based on its relationship to another
|
336
335
|
|
337
|
-
|
338
|
-
If
|
336
|
+
IF::Path#abs creates a new rio whose path is the absolute path of a Rio.
|
337
|
+
If called with an argument, it uses it as the base path, otherwise
|
339
338
|
it uses an internal base path (usually the current working directory
|
340
339
|
when it was created).
|
341
340
|
|
@@ -344,16 +343,16 @@ when it was created).
|
|
344
343
|
rio('a').abs('/usr') #=> rio('/usr/a')
|
345
344
|
end
|
346
345
|
|
347
|
-
|
346
|
+
IF::Path#rel creates a new rio with a path relative to a Rio.
|
348
347
|
|
349
348
|
rio('/tmp').chdir do
|
350
349
|
rio('/tmp/a').rel #=> rio('a')
|
351
350
|
end
|
352
351
|
rio('/tmp/b').rel('/tmp') #=> rio('b')
|
353
352
|
|
354
|
-
|
353
|
+
IF::Path#route_to and IF::Path#route_from creates a new rio with a path
|
355
354
|
representing the route to get to/from a Rio. They are based on the
|
356
|
-
methods of the same names in the URI class
|
355
|
+
methods of the same names in the ::URI class
|
357
356
|
|
358
357
|
=== Configuring a Rio
|
359
358
|
|
@@ -381,7 +380,7 @@ Rio's configuration mehods fall into three categories.
|
|
381
380
|
grande I/O methods
|
382
381
|
|
383
382
|
All of Rio's configuration and selection methods can be passed a
|
384
|
-
block, which will cause the Rio to behave as if
|
383
|
+
block, which will cause the Rio to behave as if IF::Grande#each had been called
|
385
384
|
with the block after the method.
|
386
385
|
|
387
386
|
==== IO manipulators
|
@@ -497,13 +496,13 @@ object. The result produced by the method is returned, and the object
|
|
497
496
|
is closed.
|
498
497
|
|
499
498
|
In some cases the result is modified before being returned, as when a
|
500
|
-
Rio is configured with
|
499
|
+
Rio is configured with IF::GrandeStream#chomp.
|
501
500
|
|
502
501
|
In all cases, if the result returned by the underlying object, could
|
503
502
|
itself be used for further I/O operations it is returned as a Rio. For
|
504
|
-
example: where File#dirname returns a string,
|
503
|
+
example: where File#dirname returns a string, IF::Path#dirname returns a
|
505
504
|
Rio; where Dir#read returns a string representing a directory entry,
|
506
|
-
|
505
|
+
IF::FileOrDir#read returns a Rio.
|
507
506
|
|
508
507
|
With some noteable exceptions, most of the operations available if one
|
509
508
|
were using the underlying Ruby I/O class are available to the Rio and
|
@@ -531,7 +530,7 @@ For things that exist on a file system:
|
|
531
530
|
|
532
531
|
* +dirname+, and +readlink+ return Rios instead of strings
|
533
532
|
|
534
|
-
* Rio has its own
|
533
|
+
* Rio has its own IF::Path#basename, IF::Path#join and IF::FileOrDir#symlink, which
|
535
534
|
provide similar functionality.
|
536
535
|
|
537
536
|
* The class methods which take multiple filenames
|
@@ -578,7 +577,7 @@ For directories:
|
|
578
577
|
* the class methods +mkdir+, +delete+, +rmdir+ are provided as
|
579
578
|
instance methods.
|
580
579
|
|
581
|
-
* +chdir+ is provided as an instance method.
|
580
|
+
* +chdir+ is provided as an instance method. IF::Dir#chdir returns a Rio
|
582
581
|
and passes a Rio to a block if one is provided.
|
583
582
|
|
584
583
|
* +glob+ is provided as an instance method, but returns an array of
|
@@ -600,7 +599,7 @@ appropriate. For example
|
|
600
599
|
|
601
600
|
==== Grande operators
|
602
601
|
|
603
|
-
The primary grande operator is
|
602
|
+
The primary grande operator is IF::Grande#each. +each+ is used to iterate
|
604
603
|
through Rios. When applied to a file it iterates through records in
|
605
604
|
the file. When applied to a directory it iterates through the entries
|
606
605
|
in the directory. Its behavior is modified by configuring the Rio
|
@@ -617,7 +616,7 @@ explicitly. For example:
|
|
617
616
|
rio('adir').all.files('*.rb') { |f| ... }
|
618
617
|
|
619
618
|
Because a Rio is an Enumerable, it supports +to_a+, which is the basis
|
620
|
-
for the grande subscript operator.
|
619
|
+
for the grande subscript operator. IF::Grande#[] with no arguments simply
|
621
620
|
calls to_a. With arguments it behaves as if those arguments had been
|
622
621
|
passed to the most recently called of the grande selection methods
|
623
622
|
listed above, and then calls to_a. For example to get the first ten
|
@@ -678,20 +677,22 @@ For example:
|
|
678
677
|
=== Renaming and Moving
|
679
678
|
|
680
679
|
Rio provides two methods for directly renaming objects on the
|
681
|
-
filesystem:
|
682
|
-
File#rename.
|
683
|
-
|
684
|
-
|
680
|
+
filesystem: IF::FileOrDir#rename and IF::FileOrDir#rename!.
|
681
|
+
Both of these use File#rename.
|
682
|
+
The difference between them is the returned Rio.
|
683
|
+
IF::FileOrDir#rename leaves the path of the Rio unchanged,
|
684
|
+
while IF::FileOrDir#rename! changes the path of the Rio to refer
|
685
|
+
to the renamed path.
|
685
686
|
|
686
687
|
ario = rio('a')
|
687
688
|
ario.rename('b') # file 'a' has been renamed to 'b' but 'ario' => rio('a')
|
688
689
|
ario.rename!('b') # file 'a' has been renamed to 'b' and 'ario' => rio('b')
|
689
690
|
|
690
691
|
Rio also has a +rename+ mode, which causes the path manipulation
|
691
|
-
methods
|
692
|
-
rename an object on the filesystem when they are
|
693
|
-
Rio's path. A Rio is put in +rename+ mode by calling
|
694
|
-
no arguments.
|
692
|
+
methods IF::Path#dirname=, IF::Path#filename=, IF::Path#basename= and
|
693
|
+
IF::Path#extname= to rename an object on the filesystem when they are
|
694
|
+
used to change a Rio's path. A Rio is put in +rename+ mode by calling
|
695
|
+
IF::FileOrDir#rename with no arguments.
|
695
696
|
|
696
697
|
rio('adir/afile.txt').rename.filename = 'bfile.rb' # adir/afile.txt => adir/bfile.rb
|
697
698
|
rio('adir/afile.txt').rename.basename = 'bfile' # adir/afile.txt => adir/bfile.txt
|
@@ -707,20 +708,20 @@ in the Rios created when iterating through that directory.
|
|
707
708
|
|
708
709
|
=== Deleting
|
709
710
|
|
710
|
-
The Rio methods for deleting filesystem objects are
|
711
|
-
|
712
|
-
are passed the like named methods in the FileUtils module.
|
711
|
+
The Rio methods for deleting filesystem objects are IF::File#rm, IF::Dir#rmdir,
|
712
|
+
IF::Dir#rmtree, IF::Grande#delete, and IF::Grande#delete!. +rm+, +rmdir+ and +rmtree+
|
713
|
+
are passed the like named methods in the FileUtils module. IF::Grande#delete
|
713
714
|
calls +rmdir+ for directories and +rm+ for anything else, while
|
714
|
-
|
715
|
+
IF::Grande#delete! calls IF::Dir#rmtree for directories.
|
715
716
|
|
716
|
-
* To delete something only if it is not a directory use
|
717
|
-
* To delete an empty directory use
|
718
|
-
* To delete an entire directory tree use
|
719
|
-
* To delete anything except a populated directory use
|
720
|
-
* To delete anything use
|
717
|
+
* To delete something only if it is not a directory use IF::File#rm
|
718
|
+
* To delete an empty directory use IF::Dir#rmdir
|
719
|
+
* To delete an entire directory tree use IF::Dir#rmtree
|
720
|
+
* To delete anything except a populated directory use IF::Grande#delete
|
721
|
+
* To delete anything use IF::Grande#delete!
|
721
722
|
|
722
723
|
It is not an error to call any of the deleting methods on something
|
723
|
-
that does not exist. Rio provides
|
724
|
+
that does not exist. Rio provides IF::Test#exist? and IF::Test#symlink? to check
|
724
725
|
if something exists (<tt>exist?</tt> returns false for symlinks to
|
725
726
|
non-existant object even though the symlink itself exists). The
|
726
727
|
deleting methods' purpose is to make things not exist, so calling one
|
@@ -742,7 +743,7 @@ that name exists one might do this
|
|
742
743
|
==== Using Symbolic Links
|
743
744
|
|
744
745
|
To create a symbolic link (symlink) to the file-system entry refered
|
745
|
-
to by a Rio, use
|
746
|
+
to by a Rio, use IF::FileOrDir#symlink. IF::FileOrDir#symlink differs from File#symlink
|
746
747
|
in that it calculates the path from the symlink location to the Rio's
|
747
748
|
position.
|
748
749
|
|
@@ -762,12 +763,12 @@ Note that the return value from +symlink+ is the calling Rio and not a
|
|
762
763
|
Rio refering to the symlink. This is done for consistency with the
|
763
764
|
rest of Rio.
|
764
765
|
|
765
|
-
|
766
|
-
symlink. A Rio is extended with
|
767
|
-
|
768
|
-
NoMethodError. These are both passed
|
769
|
-
File.
|
770
|
-
File#readlink.
|
766
|
+
IF::Test#symlink? can be used to test if a file-system object is a
|
767
|
+
symlink. A Rio is extended with IF::FileOrDir#readlink, and
|
768
|
+
IF::Test#lstat only if IF::Test#symlink? returns true. So for
|
769
|
+
non-symlinks, these will raise a NoMethodError. These are both passed
|
770
|
+
to their counterparts in File. IF::FileOrDir#readlink returns a Rio
|
771
|
+
refering to the result of File#readlink.
|
771
772
|
|
772
773
|
|
773
774
|
==== Using A Rio as an IO (or File or Dir)
|
@@ -781,7 +782,7 @@ circumstances.
|
|
781
782
|
Even in cases where Rio supports the required IO interface, A Rio
|
782
783
|
feature that seems to cause the most incompatibility, is its automatic
|
783
784
|
closing of files. To turn off all of Rio's automatic closing use
|
784
|
-
|
785
|
+
IF::GrandeStream#noautoclose.
|
785
786
|
|
786
787
|
For example:
|
787
788
|
require 'yaml'
|
@@ -797,8 +798,8 @@ Rio closes files automatically in three instances.
|
|
797
798
|
When reading from an IO it is closed when the end of file is
|
798
799
|
reached. While this is a reasonable thing to do in many cases,
|
799
800
|
sometimes this is not desired. To turn Rio's automatic closing on end
|
800
|
-
of file use
|
801
|
-
|
801
|
+
of file use IF::GrandeStream#nocloseoneof (it can be turned back on via
|
802
|
+
IF::GrandeStream#closeoneof)
|
802
803
|
|
803
804
|
ario = rio('afile').nocloseoneof
|
804
805
|
lines = ario[]
|
@@ -814,15 +815,16 @@ again, and will be reopened if another read operation is attempted.
|
|
814
815
|
|
815
816
|
Another time a Rio will be closed atomatically is when writing to it
|
816
817
|
with one of the copy operators (<tt><, <<, >, >></tt>). This behavior
|
817
|
-
can be turned off with
|
818
|
+
can be turned off with IF::GrandeStream#nocloseoncopy.
|
818
819
|
|
819
820
|
To turn off both of thes types of automatic closing use
|
820
|
-
|
821
|
+
IF::GrandeStream#noautoclose.
|
821
822
|
|
822
823
|
The third instance when Rio will close a file automatically is when a
|
823
824
|
file opened for one type of access receives a method which that access
|
824
|
-
mode does not support. So, the code
|
825
|
-
World").gets
|
825
|
+
mode does not support. So, the code
|
826
|
+
rio('afile').puts("Hello World").gets
|
827
|
+
will open the file for write access when the +puts+
|
826
828
|
method is received. When +gets+ is called the file is closed and
|
827
829
|
reopened with read access.
|
828
830
|
|
@@ -837,10 +839,12 @@ incorrect, some of Rio's extranious ways of closing a file may be
|
|
837
839
|
rethought.
|
838
840
|
|
839
841
|
That being said, Rio support several ways to explicitly close a
|
840
|
-
file.
|
841
|
-
|
842
|
+
file. IF::RubyIO#close will close any open Rio.
|
843
|
+
The output methods
|
844
|
+
IF::RubyIO#puts!, IF::RubyIO#putc!, IF::RubyIO#printf!, IF::RubyIO#print!, and IF::RubyIO#write!
|
845
|
+
behave as if their
|
842
846
|
counterparts without the exclamation point had been called and then
|
843
|
-
call
|
847
|
+
call IF::RubyIO#close or IF::RubyIO#close_write if the underlying IO object is
|
844
848
|
opened for duplex access.
|
845
849
|
|
846
850
|
|
@@ -850,7 +854,7 @@ A Rio is typically not explicitly opened. It opens a file
|
|
850
854
|
automatically when an input or output methed is called. For output
|
851
855
|
methods Rio opens a file with mode 'w', and otherwise opens a file
|
852
856
|
with mode 'r'. This behavior can be modified using the tersely named
|
853
|
-
methods
|
857
|
+
methods IF::GrandeStream#a, IF::GrandeStream#a!, IF::GrandeStream#r, IF::GrandeStream#r!, IF::GrandeStream#w, and IF::GrandeStream#w!, which cause
|
854
858
|
the Rio to use modes 'a','a+','r','r+','w',and 'w+' respectively.
|
855
859
|
|
856
860
|
One way to append a string to a file and close it in one line is
|
@@ -862,13 +866,13 @@ Run a cmd that must be opened for read and write
|
|
862
866
|
ans = rio(?-,'cat').w!.puts!("Hello Kitty").readlines
|
863
867
|
|
864
868
|
The automatic selection of mode can be bypassed entirely using
|
865
|
-
|
869
|
+
IF::RubyIO#mode and IF::FileOrDir#open.
|
866
870
|
|
867
871
|
If a mode is specified using +mode+, the file will still be opened
|
868
872
|
automatically, but the mode specified in the +mode+ method will be
|
869
873
|
used regardless of whether it makes sense.
|
870
874
|
|
871
|
-
A Rio can also be opened explicitly using
|
875
|
+
A Rio can also be opened explicitly using IF::RubyIO#open. +open+ takes one
|
872
876
|
parameter, a mode. This also will override all of Rio's automatic
|
873
877
|
mode selection.
|
874
878
|
|
@@ -888,7 +892,7 @@ effectively means
|
|
888
892
|
rio('afile').lines.records(1..2)
|
889
893
|
|
890
894
|
The CSV extension distingishes between items selected using
|
891
|
-
|
895
|
+
IF::GrandeStream#records and those selected using IF::GrandeStream#lines. Rio returns records
|
892
896
|
parsed into Arrays by the CSV library when +records+ is used, and
|
893
897
|
returns Strings as normal when +lines+ is used. +records+ is the
|
894
898
|
default.
|
@@ -931,7 +935,7 @@ array CSV fields, rather than just an array of strings.
|
|
931
935
|
array_of_lines[0].to_a #==>["f0", "f1"]
|
932
936
|
array_of_records[0].to_s #==>"f0,f1"
|
933
937
|
|
934
|
-
|
938
|
+
IF::CSV#csv takes two optional parameters, which are passed on to the CSV
|
935
939
|
library. They are the +field_separator+ and the +record_separator+.
|
936
940
|
|
937
941
|
rio('semisep').puts!(["h0;h1","f0;f1"])
|
@@ -945,8 +949,8 @@ using the copy operators.
|
|
945
949
|
rio('colonsep').contents #==>"h0:h1\nf0:f1\n"
|
946
950
|
|
947
951
|
Rio provides two methods for selecting fields from CSV records in a
|
948
|
-
manner similar to that provided for selecting lines --
|
949
|
-
|
952
|
+
manner similar to that provided for selecting lines -- IF::CSV#columns and
|
953
|
+
IF::CSV#skipcolumns.
|
950
954
|
|
951
955
|
rio('f.csv').puts!(["h0,h1,h2,h3","f0,f1,f2,f3"])
|
952
956
|
|
@@ -955,7 +959,7 @@ Rio#skipcolumns.
|
|
955
959
|
rio('f.csv').csv.columns(1..2).to_a #==>[["h1", "h2"], ["f1", "f2"]]
|
956
960
|
rio('f.csv').csv.skipcolumns(1..2).to_a #==>[["h0", "h3"], ["f0", "f3"]]
|
957
961
|
|
958
|
-
|
962
|
+
IF::CSV#columns can, of course be used with the +each+ and the copy
|
959
963
|
operators:
|
960
964
|
|
961
965
|
rio('f.csv').csv.columns(0..1) > rio('out').csv
|
@@ -964,8 +968,6 @@ operators:
|
|
964
968
|
|
965
969
|
==== YAML mode
|
966
970
|
|
967
|
-
<b>YAML Mode is currently in work. Please disregard this section</b>
|
968
|
-
|
969
971
|
Rio uses the YAML class from the Ruby standard library to provide
|
970
972
|
support for reading and writing YAML files. Normally
|
971
973
|
using <tt>(skip)records</tt> is identical to <tt>(skip)lines</tt> because
|
@@ -973,7 +975,7 @@ while +records+ only selects and does not specify the record-type,
|
|
973
975
|
+lines+ is the default.
|
974
976
|
|
975
977
|
The YAML extension distingishes between items selected using
|
976
|
-
|
978
|
+
IF::GrandeStream#records, IF::GrandeStream#rows and IF::GrandeStream#lines. Rio returns objects
|
977
979
|
loaded via YAML#load when +records+ is used; returns the YAML text
|
978
980
|
as a String when +rows+ is used; and
|
979
981
|
returns lines as Strings as normal when +lines+ is used.
|
@@ -1016,43 +1018,25 @@ which is aliased to #dump
|
|
1016
1018
|
}
|
1017
1019
|
rio('afile.yaml').yaml.dump(anobject)
|
1018
1020
|
|
1019
|
-
The YAML extension changes the way the grande copy operators
|
1020
|
-
interpret their argument. Rio#< (copy-from) and Rio#<< (append-from)
|
1021
|
-
treat an array as an array of objects which are converted using their
|
1022
|
-
#to_yaml method before writing.
|
1023
|
-
|
1024
|
-
rio('afile.yaml').yaml < [obj1, obj2, obj3]
|
1025
|
-
|
1026
|
-
Because of this, copying an ::Array must be done like this:
|
1027
|
-
|
1028
|
-
rio('afile.yaml').yaml < [anarray]
|
1029
1021
|
|
1030
|
-
|
1031
|
-
with each record converted using its to_yaml method.
|
1032
|
-
|
1033
|
-
For all other objects, the result of their +to_yaml+ operator is simply written.
|
1034
|
-
|
1035
|
-
rio('afile.yaml').yaml < anobject
|
1036
|
-
|
1037
|
-
Rio#> (copy-to) and Rio#>> (append-to) will fill an array with with all selected
|
1022
|
+
IF::Grande#> (copy-to) and IF::Grande#>> (append-to) will fill an array with with all selected
|
1038
1023
|
YAML documents in the Rio. For non-arrays, the yaml text is copied. (This may change
|
1039
1024
|
if a useful reasonable alternative can be found)
|
1040
1025
|
|
1041
1026
|
rio('afile.yaml').yaml > anarray # load all YAML documents from 'afile.yaml'
|
1042
1027
|
|
1043
|
-
Single objects can be written using
|
1028
|
+
Single objects can be written using IF::GrandeStream#putrec (aliased to IF::YAML#putobj and IF::YAML#dump)
|
1044
1029
|
|
1045
1030
|
rio('afile.yaml').yaml.putobj(anobject)
|
1046
1031
|
|
1047
|
-
Single objects can be loaded using
|
1032
|
+
Single objects can be loaded using IF::GrandeStream#getrec (aliase to IF::YAML#getobj and IF::YAML#load)
|
1048
1033
|
|
1049
1034
|
anobject = rio('afile.yaml').yaml.getobj
|
1050
1035
|
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
just like any other Rio. All the selection criteria are identical also.
|
1036
|
+
A Rio in yaml-mode is just like any other Rio. And all the things you
|
1037
|
+
can do with any Rio come for free. They can be iterated over using
|
1038
|
+
IF::Grande#each and read into an array using IF::Grande#[] just like
|
1039
|
+
any other Rio. All the selection criteria are identical also.
|
1056
1040
|
|
1057
1041
|
Get the first three objects into an array:
|
1058
1042
|
|
@@ -1068,10 +1052,6 @@ Selecting records using a Proc can be used as normal:
|
|
1068
1052
|
|
1069
1053
|
anarray = rio('afile.yaml').yaml(proc{|anobject| ...}).to_a
|
1070
1054
|
|
1071
|
-
One could even use the copy operator to convert a CSV file to a YAML representation of
|
1072
|
-
the same data:
|
1073
|
-
|
1074
|
-
rio('afile.yaml').yaml < rio('afile.csv').csv
|
1075
1055
|
|
1076
1056
|
|
1077
1057
|
---
|
@@ -1080,6 +1060,7 @@ the same data:
|
|
1080
1060
|
See also:
|
1081
1061
|
* RIO::Doc::SYNOPSIS
|
1082
1062
|
* RIO::Doc::HOWTO
|
1063
|
+
* RIO::Doc::EXAMPLES
|
1083
1064
|
* RIO::Rio
|
1084
1065
|
|
1085
1066
|
=end
|