rio 0.3.8 → 0.3.9
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/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
|